Voice message — accessibility

Keyboard

  • Tab order: play · track · speed (after the first play) · Přepis link · copy · each transcript sentence.
  • Play is a native <button>: Enter / Space toggle playback.
  • Track: Left / Right seek −5 / +5 s, Home / End jump to start / end; click seeks and plays.
  • Transcript sentence: Enter / Space seeks to the sentence start and plays.
  • "Zkusit znovu" and the download link of an unplayable file are native button / link.
  • The native <audio> has no controls (the DS player replaces them) but stays the real element, so the browser media session and system media keys keep working.

ARIA

  • Play: accessible name switches "Přehrát" ⇄ "Pozastavit"; the icon is decorative.
  • Track: role="slider", tabindex="0", name "Pozice přehrávání", aria-valuemin / aria-valuemax / aria-valuenow in seconds, aria-valuetext "0:12 / 0:42".
  • Speed: name "Rychlost přehrávání"; the visible text (1×, 1,5×, 2×) is the value.
  • Unplayed dot: visually hidden "Nepřehráno" (.acrm-sr).
  • Sender: visually hidden fromLabel precedes the player, as in ChatBubble.
  • Přepis link: <button aria-expanded aria-controls> pointing at the transcript block; the collapsed block is hidden, so it is out of the reading order.
  • "Přepisuji…" is role="status" (polite); "Bez řeči" and the error text are plain text; unplayable media is role="alert".
  • Sentences: role="button" tabindex="0", title "Přehrát od 0:12"; the spoken one has aria-current="true" besides the colour.
  • Copy: icon button named "Kopírovat přepis" (after copying the copied label).

Focus

  • Foundation :focus-visible ring from ds.css on play, track, speed, link, copy and sentences; nothing removes it.
  • The 44 px touch extension on phone (::before) does not change the ring, which follows the visible 32 px button.

Contrast

Ratios from packages/ui/src/tokens/tokens.css on the bubble (incoming --line-100, outgoing --accent-tint), light / dark:

  • Transcript text --fg: 16.0 / 15.1 : 1 (light in / out); 13.1 / 11.4 : 1 (dark).
  • Duration and status --fg-muted: 2.59 / 2.45 : 1 (light); 3.27 / 2.86 : 1 (dark) — below AA, kept by owner decision (RULES §18).
  • Přepis link --accent: 4.04 / 3.83 : 1 (light); 3.45 / 3.02 : 1 (dark) — meets 3 : 1, not AA 4.5 : 1 for 12 px text.
  • Error --critical-ink: 4.88 / 4.62 : 1 (light); 5.23 / 4.57 : 1 (dark).
  • Played bars --accent vs bubble ≥ 3.02 : 1; unplayed bars --ink-300 vs bubble 1.79 / 1.70 (light), 2.21 / 1.93 (dark).

Known limits

  • Unplayed track bars are below the 3 : 1 non-text minimum; position is also exposed as slider value text, so it is not colour-only.
  • Duration (--fg-muted) and the Přepis link are below AA for small text (see Contrast).
  • Sentences are role="button" spans, not native buttons — Enter / Space are handled in code.
  • .vm-time / .vm-speed use tabular-nums on time, against the RULES rule for times (fixed-width cell via invisible widest digits); open task for acrm.

Source: docs/voice-message/voice-message.a11y.md · GitLab