|Design System

Design Language

Accessibility

AI interfaces must be accessible to everyone. This page covers color contrast, focus management, ARIA patterns, and motion guidelines specific to conversational and generative AI products.

Color Contrast

WCAG 2.1 contrast ratios for all text/background combinations in the system.

TextBackgroundLevel
ForegroundBackgroundAAA
ForegroundSurfaceAAA
Muted ForegroundBackgroundAAA
SecondaryBackgroundAA
TertiaryBackgroundAA Large
AccentBackgroundAA
Contrast (text)Accent (bg)AA

Note on Tertiary

The tertiary token only passes AA Large (18px+ or 14px bold). It is intentionally low contrast for decorative labels, timestamps, and watermarks. Never use it for content the user must read to complete a task.

Focus States

Every interactive element must have a visible focus indicator for keyboard navigation.

Buttons

2px solid accent ring with 2px offset
focus-visible:ring-2 focus-visible:ring-accent focus-visible:ring-offset-2

Visible on both light and dark backgrounds. Uses ring-offset to prevent clipping.

Inputs

Border color change to accent
focus:border-accent focus:outline-none

Subtle but clear — the entire border lights up, not just an outline.

Cards / Artifact Cards

Border color change + slight shadow
focus-within:border-accent/50 focus-within:shadow-sm

Uses focus-within so child interactions highlight the container.

Navigation links

Background fill + text color change
focus-visible:bg-surface focus-visible:text-foreground

Matches hover state for consistency. No outline — fill is sufficient.

ARIA Patterns for AI Components

How to make conversational and generative AI interfaces work with assistive technology.

Chat Bubble

role="log"
role="log"aria-live="polite"aria-label="Conversation"

The chat container uses role="log" so screen readers announce new messages. Individual messages use aria-live="polite" to avoid interrupting the user.

Streaming indicator

role="status"
role="status"aria-live="polite"aria-label="Generating response"

Streaming dots are purely visual. The ARIA label communicates state to assistive tech. Updates to "Response complete" when streaming ends.

Artifact Card

role="region"
role="region"aria-expanded="true|false"aria-label="{title} artifact"

Expandable content uses aria-expanded on the toggle button. The content region is labeled with the artifact title.

Toast / Notification

role="alert"
role="alert"aria-live="assertive"

Errors and confirmations use assertive live regions. Info toasts use polite. Auto-dismiss toasts must also be accessible via a notification log.

Modal / Dialog

role="dialog"
role="dialog"aria-modal="true"aria-labelledby="title-id"

Focus traps inside the modal. Escape key closes. Focus returns to the trigger element on close.

Skeleton loader

role="status"
role="status"aria-label="Loading content"

Screen readers should announce "Loading" once, not repeat for every skeleton element. Use a single status container.

Motion & Animation

Guidelines for animation that enhances without excluding.

Respect prefers-reduced-motion

All animations must check the prefers-reduced-motion media query. When reduced motion is preferred, replace animations with instant state changes.

@media (prefers-reduced-motion: reduce) {
  * { animation-duration: 0.01ms !important; }
}

No motion-only information

Streaming dots, loading spinners, and progress bars must have text alternatives. Motion should enhance, never be the sole communicator of state.

/* Streaming indicator */
<div aria-label="Generating response">
  <span className="animate-bounce" />
  <span className="sr-only">Generating...</span>
</div>

Limit animation duration

No animation should exceed 300ms for UI transitions. Loading animations (pulse, bounce) loop but must be stoppable when content arrives.

transition-colors duration-150
transition-transform duration-200

Keyboard Navigation

Expected keyboard behavior for AI interface components.

KeyAction
EnterSend message / submit prompt
Shift + EnterNew line in chat input (no submit)
EscapeClose modal, dismiss toast, cancel streaming
TabMove focus to next interactive element
Shift + TabMove focus to previous interactive element
Arrow Up/DownNavigate between messages in chat history
Cmd/Ctrl + KOpen command palette or quick actions
Cmd/Ctrl + /Toggle sidebar