05

Design Identities

Evern uses a two-layer theme architecture that separates application chrome styling from terminal color rendering. Identities define typography, color, spacing, shape, animation, and component styling as a coordinated set of tokens.

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.

Layer 1 — Chrome Identity
Typography, colors, spacing, shape, animation
Curated in-house, not user-customizable
Layer 2 — Terminal Palette
16 ANSI colors + fg/bg/cursor/selection
Built-in presets + custom import

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.

palette resolution
fn resolve_terminal_palette(
identity: &DesignIdentity,
override_palette:
Option<&TerminalPalette>,
) -> &TerminalPalette {
override_palette
.unwrap_or(
&identity.terminal_palette
)
}

Built-In Palettes

Community Standards

Palette Mode
DraculaDark
Solarized LightLight
Solarized DarkDark
NordDark
Catppuccin MochaDark
One DarkDark
Gruvbox DarkDark
Tokyo NightDark

Evern Custom

Palette Identity Match
Evern ParchmentMinimal
Evern Brutalist MonoBrutalist
Evern Swiss MonoSwiss
Evern Material DarkPlatform Native (Android)
Evern PhosphorStandalone (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.

identity module layout
// evern-core/src/identity/built_in/
mod.rs // registry
platform_ios.rs
platform_android.rs
minimal.rs
brutalist.rs
modern.rs
swiss.rs
 
pub fn my_identity()
-> DesignIdentity {
DesignIdentity {
name: "My Identity",
type_scale: /* ... */,
chrome_colors: /* ... */,
shape: /* ... */,
spacing: /* ... */,
animation_curves: /* ... */,
animation_durations: /* ... */,
components: /* ... */,
content: /* ... */,
screens: /* ... */,
terminal_palette: /* ... */,
}
}

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:).

platform integration
// Android (Kotlin)
fun EvernTheme(
identity: DesignIdentity,
paletteOverride: TerminalPalette?,
content: @Composable () -> Unit
)
 
// iOS (Swift)
struct EvernThemeModifier:
ViewModifier {
let identity: DesignIdentity
let paletteOverride:
TerminalPalette?
}