diff --git a/src/theme/__tests__/standard-theme.test.ts b/src/theme/__tests__/standard-theme.test.ts new file mode 100644 index 00000000..5f71ea12 --- /dev/null +++ b/src/theme/__tests__/standard-theme.test.ts @@ -0,0 +1,25 @@ +import { describe, it, expect } from 'vitest'; +import { DARK_COLORS, LIGHT_COLORS } from '../tokens'; + +// The standard theme's roles from branding/APP.md ("Tokens used here"), +// which follow the webmail's app/globals.css. +describe('standard theme tokens match the webmail', () => { + it('light', () => { + expect(LIGHT_COLORS.background).toBe('#ffffff'); + expect(LIGHT_COLORS.text).toBe('#0f172a'); + expect(LIGHT_COLORS.popover).toBe('#ffffff'); + expect(LIGHT_COLORS.border).toBe('#e2e8f0'); + expect(LIGHT_COLORS.mutedForeground).toBe('#64748b'); + }); + + it('dark: white primary with near-black text on neutral greys', () => { + expect(DARK_COLORS.background).toBe('#0a0a0a'); + expect(DARK_COLORS.text).toBe('#fafafa'); + expect(DARK_COLORS.primary).toBe('#fafafa'); + expect(DARK_COLORS.primaryForeground).toBe('#171717'); + expect(DARK_COLORS.popover).toBe('#1c1c1c'); + expect(DARK_COLORS.border).toBe('rgba(128, 128, 128, 0.3)'); + expect(DARK_COLORS.mutedForeground).toBe('#a3a3a3'); + expect(DARK_COLORS.muted).toBe('#262626'); + }); +}); diff --git a/src/theme/tokens.ts b/src/theme/tokens.ts index 6850bd06..5bb1e884 100644 --- a/src/theme/tokens.ts +++ b/src/theme/tokens.ts @@ -117,30 +117,35 @@ const TAGS: TagColors = { }; export const DARK_COLORS: ThemePalette = { - primary: '#3b82f6', - primaryDark: '#2563eb', - primaryLight: '#60a5fa', - primaryBg: '#172554', + // The webmail's standard dark theme (app/globals.css .dark): a white + // primary with near-black text on neutral greys. The app used to keep a + // blue primary and zinc greys here. + primary: '#fafafa', + primaryDark: '#e5e5e5', + primaryLight: '#d4d4d4', + primaryBg: '#1e3a8a', primaryBgHover: '#1e40af', - primaryForeground: '#ffffff', - primaryBorder: 'rgba(59, 130, 246, 0.19)', + primaryForeground: '#171717', + primaryBorder: 'rgba(250, 250, 250, 0.19)', - background: '#09090b', - surface: '#18181b', - surfaceHover: '#1f1f23', - surfaceActive: '#27272a', + background: '#0a0a0a', + surface: '#262626', + surfaceHover: '#1a1a1a', + surfaceActive: '#262626', card: '#141414', cardForeground: '#fafafa', text: '#fafafa', - textSecondary: '#a1a1aa', - textMuted: '#71717a', - textInverse: '#0f172a', + textSecondary: '#a3a3a3', + textMuted: '#737373', + textInverse: '#0a0a0a', + // Links stay blue (webmail: info) so they read as links on a white-primary + // theme. textLink: '#60a5fa', - border: '#27272a', - borderLight: '#18181b', - borderFocus: '#3b82f6', + border: 'rgba(128, 128, 128, 0.3)', + borderLight: '#262626', + borderFocus: '#d4d4d4', success: '#16a34a', successBg: '#052e16', @@ -156,7 +161,7 @@ export const DARK_COLORS: ThemePalette = { infoForeground: '#ffffff', unread: '#60a5fa', - read: '#a1a1aa', + read: '#a3a3a3', starred: '#fbbf24', flagged: '#ef4444', draft: '#a78bfa', @@ -173,21 +178,21 @@ export const DARK_COLORS: ThemePalette = { tags: TAGS, - navActive: '#3b82f6', - navInactive: '#71717a', + navActive: '#fafafa', + navInactive: '#a3a3a3', navBadge: '#ef4444', - secondary: '#18181b', + secondary: '#262626', secondaryForeground: '#fafafa', - muted: '#18181b', - mutedForeground: '#a1a1aa', - accent: '#172554', - accentForeground: '#93c5fd', + muted: '#262626', + mutedForeground: '#a3a3a3', + accent: '#1e3a8a', + accentForeground: '#dbeafe', selection: 'rgba(59, 130, 246, 0.25)', selectionForeground: '#93c5fd', - popover: '#18181b', + popover: '#1c1c1c', popoverForeground: '#fafafa', chart1: '#60a5fa', chart2: '#4ade80', chart3: '#fbbf24', chart4: '#f87171', chart5: '#a78bfa',