fix(web): improve UX readability and accessibility in chat UI#910
fix(web): improve UX readability and accessibility in chat UI#910ilblackdragon merged 2 commits intostagingfrom
Conversation
Soften user bubbles, increase assistant message readability, widen message gaps, improve disabled button visibility, add keyboard focus-visible rings, fix attach button specificity, expand tree-row click targets, and increase log entry hover contrast. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
Warning You have reached your daily quota limit. Please wait up to 24 hours and I will start processing your requests again! |
There was a problem hiding this comment.
Pull request overview
This PR updates the web gateway chat UI styling and the memory tree interaction to improve readability and accessibility across the chat experience.
Changes:
- Refines chat message layout (spacing, max-width) and improves assistant message typography (padding, font size, line height).
- Enhances disabled-state styling and adds
:focus-visiblefocus rings for keyboard navigation. - Improves memory tree click targets by moving file/dir click handlers to the full row.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 4 comments.
| File | Description |
|---|---|
| src/channels/web/static/style.css | Updates chat/message styling, disabled states, focus rings, hover contrast, and scopes attach button styles. |
| src/channels/web/static/app.js | Expands memory tree click target by attaching click handlers to the full .tree-row element. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| .chat-input button:disabled { | ||
| opacity: 0.5; | ||
| opacity: 0.6; | ||
| cursor: not-allowed; | ||
| transform: none; | ||
| } |
There was a problem hiding this comment.
The hover styles for .chat-input button:hover can still apply to disabled buttons in some browsers, so a disabled send button may change background/appear interactive on hover. To match the pattern already used for .restart-btn:hover:not(:disabled), consider guarding the hover selector with :not(:disabled) and/or adding an explicit .chat-input button:disabled:hover override (background + transform).
There was a problem hiding this comment.
Fixed in d7edf02 — added :not(:disabled) guard to .chat-input button:hover, consistent with the existing .restart-btn pattern.
| .chat-input textarea:focus-visible, | ||
| .chat-input button:focus-visible, | ||
| .tab-bar button:focus-visible, | ||
| .tree-row:focus-visible { |
There was a problem hiding this comment.
.tree-row:focus-visible is styled here, but .tree-row elements are created as plain <div>s in app.js and are not focusable by default. That means keyboard users won't be able to focus tree rows, so this focus ring won’t appear and the memory tree remains effectively mouse-only. Consider making tree rows focusable (e.g., tabindex="0" + appropriate role/keyboard handlers) or adjust the approach so focus styling applies to an actual focusable element.
| .tree-row:focus-visible { | |
| .tree-row:focus-within { |
There was a problem hiding this comment.
Fixed in d7edf02 — tree-rows now have tabIndex=0 and role="treeitem", so :focus-visible will fire correctly for keyboard users.
| for (const node of nodes) { | ||
| const row = document.createElement('div'); | ||
| row.className = 'tree-row'; | ||
| row.style.paddingLeft = (depth * 16 + 8) + 'px'; | ||
|
|
||
| if (node.is_dir) { | ||
| const arrow = document.createElement('span'); | ||
| arrow.className = 'expand-arrow' + (node.expanded ? ' expanded' : ''); | ||
| arrow.textContent = '\u25B6'; | ||
| arrow.addEventListener('click', (e) => { | ||
| e.stopPropagation(); | ||
| toggleExpand(node); | ||
| }); | ||
| row.appendChild(arrow); | ||
|
|
||
| const label = document.createElement('span'); | ||
| label.className = 'tree-label dir'; | ||
| label.textContent = node.name; | ||
| label.addEventListener('click', () => toggleExpand(node)); | ||
| row.appendChild(label); | ||
|
|
||
| row.addEventListener('click', () => toggleExpand(node)); | ||
| } else { | ||
| const spacer = document.createElement('span'); | ||
| spacer.className = 'expand-arrow-spacer'; | ||
| row.appendChild(spacer); | ||
|
|
||
| const label = document.createElement('span'); | ||
| label.className = 'tree-label file'; | ||
| label.textContent = node.name; | ||
| label.addEventListener('click', () => readMemoryFile(node.path)); | ||
| row.appendChild(label); | ||
|
|
||
| row.addEventListener('click', () => readMemoryFile(node.path)); |
There was a problem hiding this comment.
Memory tree rows are <div class="tree-row"> elements with click handlers, but they are not keyboard-focusable and don’t respond to Enter/Space. Since the CSS adds .tree-row:focus-visible rings, consider adding row.tabIndex = 0 (and a suitable role, e.g. button), plus a keydown handler to trigger toggleExpand/readMemoryFile on Enter/Space. For directories, also consider reflecting state with aria-expanded so screen readers get the expanded/collapsed status.
There was a problem hiding this comment.
Fixed in d7edf02 — tree-rows now have tabIndex=0, role="treeitem", aria-expanded (for directories), and Enter/Space keydown handlers to trigger toggleExpand/readMemoryFile.
| .message.user { | ||
| align-self: flex-end; | ||
| background: var(--accent); | ||
| color: #09090b; | ||
| background: rgba(52, 211, 153, 0.15); | ||
| color: var(--accent); |
There was a problem hiding this comment.
.message.user uses a hard-coded rgba(52, 211, 153, …) background while text color is var(--accent). Since --accent is a variable, this background can drift if the accent color is ever changed (or theming is introduced). Consider deriving the translucent background from --accent (e.g., via a dedicated --accent-soft variable or color-mix(...)) so the user bubble styling stays consistent with the configured accent color.
There was a problem hiding this comment.
Fixed in d7edf02 — added --accent-soft: rgba(52, 211, 153, 0.15) CSS variable and updated .message.user to use var(--accent-soft) instead of the hardcoded value.
…a11y - Guard .chat-input button:hover with :not(:disabled) to prevent visual feedback on disabled send button - Add --accent-soft CSS variable, use in .message.user instead of hardcoded rgba - Make tree-rows keyboard-focusable (tabIndex=0, role=treeitem, aria-expanded, Enter/Space keydown handlers) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…#910) * fix(web): improve UX readability and accessibility in chat UI Soften user bubbles, increase assistant message readability, widen message gaps, improve disabled button visibility, add keyboard focus-visible rings, fix attach button specificity, expand tree-row click targets, and increase log entry hover contrast. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix(web): address PR review — hover guard, accent-soft var, tree-row a11y - Guard .chat-input button:hover with :not(:disabled) to prevent visual feedback on disabled send button - Add --accent-soft CSS variable, use in .message.user instead of hardcoded rgba - Make tree-rows keyboard-focusable (tabIndex=0, role=treeitem, aria-expanded, Enter/Space keydown handlers) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
…#910) * fix(web): improve UX readability and accessibility in chat UI Soften user bubbles, increase assistant message readability, widen message gaps, improve disabled button visibility, add keyboard focus-visible rings, fix attach button specificity, expand tree-row click targets, and increase log entry hover contrast. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix(web): address PR review — hover guard, accent-soft var, tree-row a11y - Guard .chat-input button:hover with :not(:disabled) to prevent visual feedback on disabled send button - Add --accent-soft CSS variable, use in .message.user instead of hardcoded rgba - Make tree-rows keyboard-focusable (tabIndex=0, role=treeitem, aria-expanded, Enter/Space keydown handlers) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Summary
<p>and<li>margins inside messagestransform: noneto prevent hover lift on disabled send button.chat-input textarea:disabledrule with opacity and cursor:focus-visibleoutline rings on textarea, buttons, tab-bar buttons, and tree-rows--bg-secondaryto--bg-tertiaryfor better contrast.chat-input .attach-btnto avoid conflicts, removed unintended bold weightTest plan
🤖 Generated with Claude Code