Gryt

User Interface

Design system, themes, and accessibility

The Gryt client is built with Radix Themes, Motion (formerly Framer Motion) for animations, and supports dark/light themes with system preference detection.

Tech Stack

  • Radix Themes — component library (buttons, dialogs, cards, text fields, etc.)
  • CSS variables — theming and color tokens
  • Motion — layout animations and transitions (AnimatePresence, motion.div)
  • React Icons — icon set (Material Design icons via react-icons/md)

Theming

Gryt uses the Radix Themes <Theme> provider with configurable accent color, gray color, radius, and appearance (light/dark/system). The useTheme() hook exposes:

  • resolvedAppearance"light" or "dark" after resolving system preference
  • accentColor — Radix accent color (e.g. "iris", "blue")
  • grayColor — Radix gray variant
  • radius — border radius scale
  • uiScale — global UI scaling factor
  • chatFontSize — font size for chat messages

Theme preferences are persisted per user and sync across sessions.

CSS Variables

Custom variables extend the Radix theme tokens:

:root {
  --default-font-family: "Atkinson Hyperlegible Next", sans-serif;
  --code-font-family: "Atkinson Hyperlegible Mono", monospace;
  --scaling: 1.15;
}

.dark {
  --color-background: #111318;
  --color-panel-solid: #1a1d24;
}

.light {
  --color-background: #eef0f4;
  --color-panel-solid: #ffffff;
}

Typography

Gryt uses Atkinson Hyperlegible Next as its primary typeface and Atkinson Hyperlegible Mono for monospaced text. Created by the Braille Institute of America, these fonts maximize character differentiation for users with low vision while looking great for everyone. See the Accessibility page for more details.

Both fonts ship as variable WOFF2 files supporting weights 200–900.

Invites and Membership

Gryt servers are invite-only.

  • The first user to join a brand-new server automatically becomes owner/admin.
  • After that, new users must join via an invite link.
  • Existing members can rejoin without an invite.

Admins can manage invites in Server settings > Invites:

  • Create single-use or multi-use invites (max uses)
  • Create infinite-use invites
  • Revoke invites (revocation is permanent)

Each invite shows its usage:

  • Finite: uses remaining / max uses
  • Infinite: uses consumed / ∞

Emoji System

Standard Emoji Shortcodes

Type :smile: or any other standard shortcode in the chat input and it will be rendered as the corresponding Unicode emoji. Over 1800 standard emojis are supported via the gemoji dataset, including names, aliases, and tags.

Custom Server Emojis

Server admins can upload custom emojis (PNG, JPEG, WebP, GIF, or SVG). Animated GIFs are preserved as GIFs; all other formats are resized to 128px height and converted to PNG. Multiple images can be selected at once, and .zip archives containing images are automatically extracted. Shortcodes are derived from filenames and deduplicated against existing server emojis. Custom emojis are used with the same :shortcode: syntax and render as inline images in messages.

Each emoji shows an individual upload progress bar during upload, which is especially useful for larger GIF files. After uploading, admins can rename any emoji by clicking the edit icon in the emoji list.

Emoji Autocomplete

When you type : followed by two or more characters, a popup appears above the chat input showing matching emojis. The search uses a ranked algorithm:

  1. Prefix match:smi matches :smile:
  2. Word-boundary match:up matches :thumbs_up:
  3. Substring match:rin matches :grinning:
  4. Tag/alias match:happy matches emojis tagged "happy"

Navigate with arrow keys, press Enter/Tab to insert, or click a result. Custom server emojis are included and marked with a "custom" badge.

Rich Text Input

The chat input is a contenteditable editor that renders emojis inline. Standard emojis appear as native Unicode characters and custom emojis appear as small inline images, so you can see exactly what your message will look like before sending.

Application Structure

The client is organized into feature packages under src/packages/:

PackagePurpose
audioMicrophone, audio pipeline, RNNoise, push-to-talk, speakers
commonAuth (Keycloak), shared hooks, utility functions
dialoguesDialog/modal components
libShared utilities
mobileMobile-related hooks
settingsSettings UI, theme, server management
signUpSign-up/onboarding flow
socketSocket.IO connections, server list, member sidebar
webRTCSFU connection, voice room, camera, screen share

Top-level components live in src/components/ and include the titlebar, browser banner, error boundary, welcome screen, and microphone debug overlay.

Accessibility

See the Accessibility guide for our commitment and current status. Key points:

  • Atkinson Hyperlegible typeface for maximum legibility
  • Radix UI components provide built-in ARIA attributes and keyboard interaction
  • Dark/light themes with system preference detection
  • Keyboard shortcuts for mute, deafen, disconnect, and push-to-talk
  • Ongoing work on full keyboard navigation, screen reader support, and focus management

On this page