Two-Layer Architecture
Evern uses a two-layer theme architecture that separates the application UI ("chrome") from the terminal rendering surface. Most terminal clients treat theming as a 16-color palette swap; Evern's approach allows the application UI and terminal surface to be styled independently.
An identity defines the full set of chrome tokens — typography, colors, spacing, shape, animation, and component styling — together with a matched terminal palette. Users can override just the terminal palette while keeping the chrome identity's tokens intact.
Chrome Identity Tokens
All tokens are Rust structs exposed via UniFFI. Each DesignIdentity defines a complete set of visual parameters that the platform UI maps to native styling.
| Token Group | Controls | Properties |
|---|---|---|
| TypeScale | 16 text style roles (display_large through caption) | Family, weight, size, tracking, line height, text transform |
| ChromeColorPalette | Backgrounds, content, accent, semantic, structure, special | 20 required + 3 optional named color tokens (see full list below) |
| ShapeScale | Corner radius values | none, extra_small, small, medium, large, extra_large, full |
| SpacingScale | Layout spacing | Based on base_unit: xxs through xxxl |
| AnimationCurves | Motion timing | default, enter, exit, spring, snappy, slow (cubic bezier) |
| AnimationDurations | Motion speed | instant, fast, medium, slow, glacial (ms) |
| ComponentOverrides | Button, card, input, nav, separator, status indicator | Per-component styling properties (see detail below) |
| ContentOverrides | Diff, code block, tool use, thinking block, collapse | AI output rendering variants (see detail below) |
| ScreenOverrides | Server list, session screen, tab style | Layout and structure variants (see detail below) |
ChromeColorPalette — Full Token List
The ChromeColorPalette struct contains 20 required color tokens and 3 optional tokens (23 total). All colors are specified as RGBA values.
| Category | Token | Description |
|---|---|---|
| Backgrounds | background |
Primary app background |
surface |
Card and container fill | |
surface_variant |
Secondary surface (e.g., sidebar, grouped sections) | |
surface_elevated |
Elevated surfaces (sheets, dialogs, popovers) | |
| Content | on_background |
Primary text on background |
on_surface |
Primary text on surface | |
on_surface_variant |
Secondary/muted text on surface | |
| Accent | primary |
Main accent color (buttons, links, active states) |
on_primary |
Text/icon on primary-colored backgrounds | |
secondary |
Secondary accent (tags, badges, less prominent controls) | |
on_secondary |
Text/icon on secondary-colored backgrounds | |
| Semantic | error |
Error state color |
on_error |
Text/icon on error-colored backgrounds | |
success |
Success state color | |
warning |
Warning state color | |
| Structure | separator |
Divider lines, borders |
ghost |
Ghost/transparent button backgrounds, subtle hover states | |
scrim |
Modal overlay background | |
| Special (optional) | accent_gradient_start |
Start color for gradient accents (defaults to primary if absent) |
accent_gradient_end |
End color for gradient accents (defaults to primary if absent) |
|
texture_overlay |
Tint color for texture overlays such as paper grain (defaults to transparent if absent) |
ComponentOverrides
ComponentOverrides lets each identity customize the appearance and behavior of core UI components beyond what the base token groups provide.
| Component | Key Properties |
|---|---|
| ButtonStyle | corner_radius, border_width, filled_style, text_transform, haptic_style |
| CardStyle | corner_radius, border_width, elevation, padding, background |
| InputStyle | corner_radius, border_width, cursor_style (Line / Block / Underline) |
| NavStyle | variant (Standard / Minimal / Prominent), blur_background, separator_visible |
| SeparatorStyle | width, inset_start, inset_end |
| StatusIndicatorStyle | connected / connecting / disconnected colors, variant (Dot / Badge / Bar / Pulse) |
ContentOverrides
ContentOverrides controls how AI-generated and structured content blocks are rendered within the session view.
| Component | Key Properties |
|---|---|
| DiffStyle | decoration, line_background, border_markers |
| CodeBlockStyle | header, line_numbers |
| ToolUseStyle | variant |
| ThinkingBlockStyle | variant |
| CollapseStyle | indicator, preview_lines |
ScreenOverrides
ScreenOverrides controls the layout and structural variants used by top-level screens.
| Component | Key Properties |
|---|---|
| ServerListStyle | layout, item, header |
| SessionScreenStyle | header, terminal, toolbar, composer |
| SessionTabStyle | Tab appearance and active indicator styling |
Shipped Identities
All shipped identities are available to every user for free. There is no identity gating — the design system is part of the core product experience.
| Identity | Aesthetic | Key Tokens | Matched Palette |
|---|---|---|---|
| Platform Native (iOS) | Apple HIG — SF Pro, grouped inset cards, frosted glass | 10dp radius, #007AFF primary, FrostedGlass effect | Solarized Dark |
| Platform Native (Android) | Material 3 — Roboto, dynamic colors, card-based | 12dp radius, #6750A4 primary, tonal elevation | Evern Material Dark |
| Minimal | Japanese wabi-sabi — Zen Kaku Gothic, warm parchment, extreme negative space | #F7F5F0 bg, #C4573A accent, paper texture overlay | Evern Parchment |
| Brutalist | Raw industrial — Oswald condensed, all-caps, pure black, zero border-radius | #0A0A0A bg, #FF2D20 red, 0dp all radii, linear animation | Evern Brutalist Mono |
| Modern | Vercel/Linear — Inter, JetBrains Mono, gradient accents, glow effects | #000000 bg, gradient accent, FrostedGlass + BorderGlow | Tokyo Night |
| Swiss | International Typographic Style — Hanken Grotesk, strict grayscale, red used exactly twice | #FFFFFF bg, #E03E2F accent, no effects ("restraint is the effect") | Evern Swiss Mono |
Each identity is a complete design system — typography, spacing, shape, color, animation, component styling, and content rendering all change together.
Terminal Palette Model
The terminal palette defines the rendering surface: 16 ANSI colors (black through bright white), foreground/background, cursor, selection colors, and optional syntax highlighting tokens for tree-sitter integration.
Syntax Colors (Optional)
Palettes can include extended tokens for syntax highlighting: keyword, string, number, comment, function, variable, type, constant, operator, punctuation, attribute, tag, and diff colors (added, removed, changed).
Palette Override
Users can override the terminal palette independently of the chrome identity. Only the terminal surface colors change — chrome tokens remain intact.
Built-In Palettes
Community Standards
| Palette | Mode |
|---|---|
| Dracula | Dark |
| Solarized Light | Light |
| Solarized Dark | Dark |
| Nord | Dark |
| Catppuccin Mocha | Dark |
| One Dark | Dark |
| Gruvbox Dark | Dark |
| Tokyo Night | Dark |
Evern Custom
| Palette | Identity Match |
|---|---|
| Evern Parchment | Minimal |
| Evern Brutalist Mono | Brutalist |
| Evern Swiss Mono | Swiss |
| Evern Material Dark | Platform Native (Android) |
| Evern Phosphor | Standalone (no matched identity) |
Evern Phosphor is a green-on-black CRT-style palette available in the override palette pool. It is not matched to any shipped identity. A dedicated Retro CRT identity is under consideration for a future release.
Import Formats
| Format | Extension | Color Format | Notes |
|---|---|---|---|
| iTerm2 | .itermcolors |
XML plist, RGB 0.0-1.0 floats | Conversion: floor(component * 255) |
| Windows Terminal | .json |
Direct hex strings | Handles full settings.json or single scheme |
| Alacritty | .yaml / .toml |
Hex with 0x or # prefix |
Supports both legacy YAML and v0.13+ TOML |
Auto-detection identifies the format by file extension, then validates content structure (XML header, "schemes" key, "colors:" section). Missing fields fall back gracefully: cursor defaults to foreground, selection to bright black, bright colors to normal variants.
Importing a Theme
Evern can import terminal color palettes from iTerm2, Alacritty, and Windows Terminal theme files. The imported palette becomes available as a terminal palette override, leaving the active chrome identity unchanged.
| Step | Action |
|---|---|
| 1 | Export or download a theme file from your source terminal. Supported extensions: .itermcolors, .yaml / .toml, or .json. |
| 2 | In Evern, navigate to Settings → Identity → Terminal Colors → Use Custom Palette → Import. |
| 3 | Select the theme file. Evern auto-detects the format by file extension and parses the color values. |
| 4 | The imported palette appears in the override palette picker and can be applied to any identity. |
| 5 | Missing fields default gracefully: cursor defaults to the foreground color, selection defaults to bright black, and missing bright colors fall back to their normal variants. |
Note: Theme import via the app UI is planned for Phase 5 and is not yet implemented. The import format parsers exist in the Rust core, but the Settings UI flow described above is not yet available.
Creating a Custom Identity
Identities are defined as Rust structs in evern-core/src/identity/built_in/. Each identity is a module that exports a function returning a DesignIdentity struct containing all token groups (TypeScale, ChromeColorPalette, ShapeScale, SpacingScale, AnimationCurves, AnimationDurations, ComponentOverrides, ContentOverrides, ScreenOverrides) and a matched TerminalPalette.
Steps
1. Create a new module file in evern-core/src/identity/built_in/ (e.g., my_identity.rs).
2. Define a public function that returns a DesignIdentity struct with all required token groups populated.
3. Register the new identity in the identity module's list (the mod.rs file that enumerates available identities).
4. Rebuild the Rust core. Custom identities require recompilation since they are compiled into the binary.
Future: Theme Bundles
A .evern-theme bundle format for marketplace distribution is planned for v1.4. This will allow identities to be packaged and shared without rebuilding the Rust core. This format is not yet implemented.
Platform Integration
Android — Compose Theme Provider
ChromeColorPalette maps to MaterialTheme.colorScheme. TypeScale maps to Typography with font resolution from assets. ShapeScale maps to Compose Shapes. Remaining tokens (spacing, animation, components) are provided via CompositionLocal.
iOS — SwiftUI Environment
A ViewModifier injects EvernColors, EvernTypeScale, EvernShapes, EvernSpacing, EvernAnimation, EvernComponents, EvernEffects, and TerminalPalette into the SwiftUI environment. Custom fonts are loaded via UIFont.registerFont(from:).