/ web / src / themes / presets.ts
presets.ts
  1  import type { DashboardTheme, ThemeTypography, ThemeLayout } from "./types";
  2  
  3  /**
  4   * Built-in dashboard themes.
  5   *
  6   * Each theme defines its own palette, typography, and layout so switching
  7   * themes produces visible changes beyond just color — fonts, density, and
  8   * corner-radius all shift to match the theme's personality.
  9   *
 10   * Theme names must stay in sync with the backend's
 11   * `_BUILTIN_DASHBOARD_THEMES` list in `hermes_cli/web_server.py`.
 12   */
 13  
 14  // ---------------------------------------------------------------------------
 15  // Shared typography / layout presets
 16  // ---------------------------------------------------------------------------
 17  
 18  /** Default system stack — neutral, safe fallback for every platform. */
 19  const SYSTEM_SANS =
 20    'system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif';
 21  const SYSTEM_MONO =
 22    'ui-monospace, "SF Mono", "Cascadia Mono", Menlo, Consolas, monospace';
 23  
 24  const DEFAULT_TYPOGRAPHY: ThemeTypography = {
 25    fontSans: SYSTEM_SANS,
 26    fontMono: SYSTEM_MONO,
 27    baseSize: "15px",
 28    lineHeight: "1.55",
 29    letterSpacing: "0",
 30  };
 31  
 32  const DEFAULT_LAYOUT: ThemeLayout = {
 33    radius: "0.5rem",
 34    density: "comfortable",
 35  };
 36  
 37  // ---------------------------------------------------------------------------
 38  // Themes
 39  // ---------------------------------------------------------------------------
 40  
 41  export const defaultTheme: DashboardTheme = {
 42    name: "default",
 43    label: "Hermes Teal",
 44    description: "Classic dark teal — the canonical Hermes look",
 45    palette: {
 46      background: { hex: "#041c1c", alpha: 1 },
 47      midground: { hex: "#ffe6cb", alpha: 1 },
 48      foreground: { hex: "#ffffff", alpha: 0 },
 49      warmGlow: "rgba(255, 189, 56, 0.35)",
 50      noiseOpacity: 1,
 51    },
 52    typography: DEFAULT_TYPOGRAPHY,
 53    layout: DEFAULT_LAYOUT,
 54  };
 55  
 56  export const midnightTheme: DashboardTheme = {
 57    name: "midnight",
 58    label: "Midnight",
 59    description: "Deep blue-violet with cool accents",
 60    palette: {
 61      background: { hex: "#0a0a1f", alpha: 1 },
 62      midground: { hex: "#d4c8ff", alpha: 1 },
 63      foreground: { hex: "#ffffff", alpha: 0 },
 64      warmGlow: "rgba(167, 139, 250, 0.32)",
 65      noiseOpacity: 0.8,
 66    },
 67    typography: {
 68      ...DEFAULT_TYPOGRAPHY,
 69      fontSans: `"Inter", ${SYSTEM_SANS}`,
 70      fontMono: `"JetBrains Mono", ${SYSTEM_MONO}`,
 71      fontUrl:
 72        "https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500;700&display=swap",
 73      letterSpacing: "-0.005em",
 74    },
 75    layout: {
 76      ...DEFAULT_LAYOUT,
 77      radius: "0.75rem",
 78    },
 79  };
 80  
 81  export const emberTheme: DashboardTheme = {
 82    name: "ember",
 83    label: "Ember",
 84    description: "Warm crimson and bronze — forge vibes",
 85    palette: {
 86      background: { hex: "#1a0a06", alpha: 1 },
 87      midground: { hex: "#ffd8b0", alpha: 1 },
 88      foreground: { hex: "#ffffff", alpha: 0 },
 89      warmGlow: "rgba(249, 115, 22, 0.38)",
 90      noiseOpacity: 1,
 91    },
 92    typography: {
 93      ...DEFAULT_TYPOGRAPHY,
 94      fontSans: `"Spectral", Georgia, "Times New Roman", serif`,
 95      fontMono: `"IBM Plex Mono", ${SYSTEM_MONO}`,
 96      fontUrl:
 97        "https://fonts.googleapis.com/css2?family=Spectral:wght@400;500;600;700&family=IBM+Plex+Mono:wght@400;500;700&display=swap",
 98    },
 99    layout: {
100      ...DEFAULT_LAYOUT,
101      radius: "0.25rem",
102    },
103    colorOverrides: {
104      destructive: "#c92d0f",
105      warning: "#f97316",
106    },
107  };
108  
109  export const monoTheme: DashboardTheme = {
110    name: "mono",
111    label: "Mono",
112    description: "Clean grayscale — minimal and focused",
113    palette: {
114      background: { hex: "#0e0e0e", alpha: 1 },
115      midground: { hex: "#eaeaea", alpha: 1 },
116      foreground: { hex: "#ffffff", alpha: 0 },
117      warmGlow: "rgba(255, 255, 255, 0.1)",
118      noiseOpacity: 0.6,
119    },
120    typography: {
121      ...DEFAULT_TYPOGRAPHY,
122      fontSans: `"IBM Plex Sans", ${SYSTEM_SANS}`,
123      fontMono: `"IBM Plex Mono", ${SYSTEM_MONO}`,
124      fontUrl:
125        "https://fonts.googleapis.com/css2?family=IBM+Plex+Sans:wght@400;500;600&family=IBM+Plex+Mono:wght@400;500&display=swap",
126    },
127    layout: {
128      ...DEFAULT_LAYOUT,
129      radius: "0",
130    },
131  };
132  
133  export const cyberpunkTheme: DashboardTheme = {
134    name: "cyberpunk",
135    label: "Cyberpunk",
136    description: "Neon green on black — matrix terminal",
137    palette: {
138      background: { hex: "#040608", alpha: 1 },
139      midground: { hex: "#9bffcf", alpha: 1 },
140      foreground: { hex: "#ffffff", alpha: 0 },
141      warmGlow: "rgba(0, 255, 136, 0.22)",
142      noiseOpacity: 1.2,
143    },
144    typography: {
145      ...DEFAULT_TYPOGRAPHY,
146      fontSans: `"Share Tech Mono", "JetBrains Mono", ${SYSTEM_MONO}`,
147      fontMono: `"Share Tech Mono", "JetBrains Mono", ${SYSTEM_MONO}`,
148      fontUrl:
149        "https://fonts.googleapis.com/css2?family=Share+Tech+Mono&family=JetBrains+Mono:wght@400;700&display=swap",
150    },
151    layout: {
152      ...DEFAULT_LAYOUT,
153      radius: "0",
154    },
155    colorOverrides: {
156      success: "#00ff88",
157      warning: "#ffd700",
158      destructive: "#ff0055",
159    },
160  };
161  
162  export const roseTheme: DashboardTheme = {
163    name: "rose",
164    label: "Rosé",
165    description: "Soft pink and warm ivory — easy on the eyes",
166    palette: {
167      background: { hex: "#1a0f15", alpha: 1 },
168      midground: { hex: "#ffd4e1", alpha: 1 },
169      foreground: { hex: "#ffffff", alpha: 0 },
170      warmGlow: "rgba(249, 168, 212, 0.3)",
171      noiseOpacity: 0.9,
172    },
173    typography: {
174      ...DEFAULT_TYPOGRAPHY,
175      fontSans: `"Fraunces", Georgia, serif`,
176      fontMono: `"DM Mono", ${SYSTEM_MONO}`,
177      fontUrl:
178        "https://fonts.googleapis.com/css2?family=Fraunces:opsz,wght@9..144,400;9..144,500;9..144,600&family=DM+Mono:wght@400;500&display=swap",
179    },
180    layout: {
181      ...DEFAULT_LAYOUT,
182      radius: "1rem",
183    },
184  };
185  
186  export const BUILTIN_THEMES: Record<string, DashboardTheme> = {
187    default: defaultTheme,
188    midnight: midnightTheme,
189    ember: emberTheme,
190    mono: monoTheme,
191    cyberpunk: cyberpunkTheme,
192    rose: roseTheme,
193  };