Skip to content

refactor(ui): tokenise context-warning banner + a11y fixes - #81

Merged
jonnyparris merged 2 commits into
mainfrom
refactor/ui-tokens-and-banner-a11y
May 25, 2026
Merged

refactor(ui): tokenise context-warning banner + a11y fixes#81
jonnyparris merged 2 commits into
mainfrom
refactor/ui-tokens-and-banner-a11y

Conversation

@jonnyparris

Copy link
Copy Markdown
Owner

First-pass refactor guided by the newly-adapted frontend-ui-engineering skill (from addyosmani/agent-skills, tuned for Dodo's vanilla-HTML + Kumo-token stack).

What

Three fixes on and around the context-usage warning surface:

  1. #context-warning banner — was a <div onclick> with hardcoded #e67e22 and click-anywhere-to-dismiss. Replaced with a proper sticky banner using --warning / --text-warning tokens (matching the existing-but-unused .banner.warn rule), aria-live="polite", and a real <button> with aria-label="Dismiss context warning".
  2. Token-meter colours in dodo-chat.js#e74c3c / #e67e22var(--text-danger) / var(--text-warning). Theme-aware now.
  3. session-item role="button" — only handled Enter, not Space. ARIA-spec violation. Added Space handler with preventDefault() plus aria-label so screen readers announce the session title.

Why this scope

These three are concrete, named violations of the skill's red-flag list:

  • <div onclick> instead of <button>
  • hardcoded hex when a token exists
  • icon/role-button without proper keyboard support
  • inline styles
  • no aria-live on a status banner

Bounded to one logical surface so it's reviewable.

Verification

  • npm run typecheck
  • npm run lint
  • npm test ✓ (777/777)
  • Behaviour preserved: banner appears at >80% context, hides otherwise, resets on session change/delete. Dismissal is still until next update tick.

Not in scope (deferred)

The skill audit also flagged: <div role="button"> items in dodo-files.js / dodo-kanban.js (large, touches drag-and-drop selection state), and the 1021-line monolithic index.html (worth splitting, but a separate change). Happy to do either as follow-ups.

Skill

Lives at ~/agent-hq/.opencode/skill/frontend-ui-engineering/SKILL.md (committed here) — vanilla-HTML/Kumo-token flavour, positioned to complement html / web-accessibility / design-ux rather than overlap.

Three fixes guided by the new frontend-ui-engineering skill, all on the
context-usage warning surface plus one neighbour:

1. #context-warning was a <div onclick> styled with hardcoded #e67e22
   and a click-anywhere-to-dismiss handler. Replaced with a proper
   sticky banner using --warning / --text-warning tokens (matching the
   existing-but-unused .banner.warn rule), aria-live='polite' for
   announce-on-show, and a real <button> with aria-label='Dismiss
   context warning' that handles keyboard close.

2. updateTokenSummary() in dodo-chat.js coloured the token meter via
   hardcoded #e74c3c / #e67e22. Switched to --text-danger /
   --text-warning. Theme-aware now.

3. session-item's role='button' only handled Enter, not Space — an
   ARIA-spec violation for any element with role=button. Added Space
   handler with preventDefault() (otherwise the page scrolls) plus
   aria-label so screen readers announce the session title.

The banner's show/hide functions extracted to showContextWarning /
hideContextWarning so the three call sites (token-summary update,
deleteSession, selectSession) stop writing style.display directly and
the dismiss button's markup isn't blown away on every update.

Behaviour preserved: banner appears at >80% context, hides otherwise,
and resets on session change/delete. Dismissal is until the next
update tick — same as before, just no longer a click-anywhere foot-gun.

typecheck + lint + 777 tests green.
aria-label on an element hides inner text from AT (only the label is
announced). The session-item div contains both the title and a meta line
with status + timestamp; with aria-label='Open session ${title}' screen
readers would lose access to status and timestamp.

Removing aria-label lets accessible-name computation fall through to the
title + meta children, matching what sighted users see. role='button' +
the surrounding context still convey that it's actionable.

beep-boop-ruskin-agent-🤖
@jonnyparris
jonnyparris merged commit 6f2bc9a into main May 25, 2026
1 of 2 checks passed
@jonnyparris
jonnyparris deleted the refactor/ui-tokens-and-banner-a11y branch May 25, 2026 13:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant