Files
webui/THEMES.md
Nathan Esquenazi 2f58724863 fix: light theme final polish -- sidebar, roles, chips, all interactive elements
* fix: light theme sidebar, roles, chips, active states -- full polish

Comprehensive light theme overrides for every remaining hardcoded
dark-theme element:

Sidebar:
- Session items: warm dark text instead of faint muted gray
- Active session: blue accent (matching --blue) instead of washed-out gold
- Pin stars/headers: deep gold #996b15 instead of bright yellow #f5c542
- Session actions gradient: light bg instead of dark overlay
- Search input: dark borders, proper focus ring

Role labels:
- You: solid #2d6fa3 blue instead of faint rgba(124,185,255,0.65)
- Hermes: solid #8a6520 gold instead of faint rgba(201,168,76,0.6)
- Role icons: proper bg/border contrast for light backgrounds

Chips and interactive elements:
- Project chips: dark borders, dark hover states
- Model chip: blue accent matching theme
- New chat button: blue accent borders
- All hover states: rgba(0,0,0,.XX) instead of rgba(255,255,255,.XX)

Other surfaces:
- Composer box borders and focus ring
- Tool cards, cron items, suggestions
- File tree hover, preview badges
- Profile/workspace dropdown hovers
- Settings, nav tooltips

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* docs: update THEMES.md with all current CSS variables

Added typography variables (--strong, --em, --code-text, --code-inline-bg,
--pre-text) to the custom theme guide. Added note about light theme
selector overrides needed for hover/border contrast.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-04 22:11:42 -07:00

6.0 KiB

Hermes Web UI — Themes

Hermes Web UI supports pluggable color themes. Five themes ship built-in, and you can create your own with pure CSS — no Python changes needed.


Switching Themes

Settings panel: Click the gear icon, select a theme from the dropdown. The preview is instant — the UI updates as you click through options.

Slash command: Type /theme dark or /theme light in the composer.

Themes persist across page reloads and server restarts (stored in settings.json server-side, with localStorage for flicker-free loading).


Built-in Themes

Theme Description
Dark (default) Deep navy/indigo with muted blue accents. Easy on the eyes for long sessions.
Light Warm off-white with dark text. High contrast for bright environments.
Slate Warm charcoal, lighter than Dark. Easier on the eyes for extended use.
Solarized Dark Ethan Schoonover's classic dark palette. Teal background, warm accents.
Monokai Warm dark theme inspired by the Monokai editor scheme. Green/pink accents.
Nord Arctic blue-gray palette from the Nord color system. Calm and minimal.
Custom themes Any string accepted by settings.json, POST /api/settings, and /theme if added to the picker/command list. Pure CSS variables only.

Creating a Custom Theme

A theme is a CSS block that overrides the color variables. Add it to static/style.css (or a separate file that you link after the main stylesheet).

Step 1: Define your theme block

Every color in the UI comes from these CSS variables:

:root[data-theme="your-theme-name"] {
  /* Core palette */
  --bg: #1a1a2e;          /* Main background */
  --sidebar: #16213e;      /* Sidebar background */
  --border: rgba(255,255,255,0.08);   /* Subtle borders */
  --border2: rgba(255,255,255,0.14);  /* Stronger borders */
  --text: #e8e8f0;         /* Primary text color */
  --muted: #8888aa;        /* Secondary/muted text */
  --accent: #e94560;       /* Accent color (errors, warnings, delete) */
  --blue: #7cb9ff;         /* Primary action color (links, active states) */
  --gold: #c9a84c;         /* Secondary accent (pinned items, gold highlights) */
  --code-bg: #0d1117;      /* Code block background */

  /* Surface and chrome (required for full theme polish) */
  --surface: #1a2535;      /* Dropdowns, popups, toast, approval card */
  --topbar-bg: rgba(22,33,62,.98);   /* Topbar background */
  --main-bg: rgba(26,26,46,0.5);    /* Main chat area background */
  --input-bg: rgba(255,255,255,.04); /* Input/button subtle backgrounds */
  --hover-bg: rgba(255,255,255,.06); /* Hover state backgrounds */
  --focus-ring: rgba(124,185,255,.35); /* Focus border color */
  --focus-glow: rgba(124,185,255,.08); /* Focus box-shadow glow */

  /* Typography (required for readable text across themes) */
  --strong: #fff;          /* Bold text in messages */
  --em: #c9c9e8;           /* Italic text in messages */
  --code-text: #f0c27f;    /* Inline code text color */
  --code-inline-bg: rgba(0,0,0,.35); /* Inline code background */
  --pre-text: #e2e8f0;     /* Code block text color */
}

The core palette controls the overall mood. The surface/chrome and typography variables are part of the standard theme contract — define all of them for a complete theme.

For light themes, you also need :root[data-theme="name"] overrides for elements that use rgba(255,255,255,.XX) hover/border effects (these are invisible on light backgrounds). See the built-in light theme for the full pattern — it overrides ~45 selectors for proper dark-on-light contrast on hover states, borders, chips, role labels, session items, and interactive elements.

Step 2: Add it to the theme picker (optional)

To make your theme appear in the Settings dropdown, add an <option> to the theme <select> in static/index.html:

<option value="your-theme-name">Your Theme Name</option>

And update the /theme command's valid theme list in static/commands.js.

Step 3: Test it

Switch to your theme via /theme your-theme-name or the Settings panel. Check these areas:

  • Sidebar session list (hover states, active state, project borders)
  • Message bubbles (user vs assistant styling)
  • Code blocks (background contrast, copy button visibility)
  • Tool cards (running indicator, expand/collapse)
  • Settings panel and login page
  • Mobile layout (hamburger sidebar, bottom nav)

Tips

  • Light themes need scrollbar and selection overrides, plus the full text/code set (--strong, --em, --code-text, --code-inline-bg, --pre-text) or they will look broken.
  • The logo gradient uses --accent automatically, so it adapts to your theme without extra work.
  • Prism.js syntax highlighting uses its own CDN stylesheet (Tomorrow theme). It works well on dark themes; on light themes the contrast is acceptable but not perfect. Custom Prism theme support is planned for a future update.
  • No server changes needed. The theme setting in settings.json accepts any string — your custom theme name will persist without code changes.

How Themes Work Internally

  1. Each theme is a :root[data-theme="name"] CSS block that overrides variables.
  2. Switching themes sets document.documentElement.dataset.theme = name in JS.
  3. A tiny inline <script> in <head> reads localStorage before the stylesheet loads — this prevents a flash of the wrong theme on page load.
  4. The theme preference is saved server-side via POST /api/settings and loaded on boot via GET /api/settings.
  5. The /theme command and Settings dropdown both update the DOM, localStorage, and server settings simultaneously.

Contributing a Theme

To contribute a new built-in theme:

  1. Add your :root[data-theme="name"] block to static/style.css
  2. Add the <option> to the Settings panel in static/index.html
  3. Add the theme name to the valid list in cmdTheme() in static/commands.js
  4. Test on desktop and mobile
  5. Open a PR — themes are pure CSS additions with no backend changes needed