feat(desktop): theme polish, prose chat typography, composer chrome
- DS tokens/midground, Backdrop, scoped scrollbars, typography plugin + prose - Composer liquid/radius utilities, thread font parity, tool/thinking cues - File tree label scale, preview flex, thread retry loading + streaming tests
This commit is contained in:
@@ -149,6 +149,11 @@ function lightColors(seed: DesktopTheme, skinName: string): DesktopThemeColors {
|
||||
border,
|
||||
input: mix('#e2e2e6', accent, 0.18),
|
||||
ring: accent,
|
||||
// Brand-accent stroke layer carries the seed's identity color into the
|
||||
// light palette intact (no mix-with-white softening) so DS components
|
||||
// and `bg-midground/N` surfaces still read as branded against white.
|
||||
midground: seed.colors.midground ?? accent,
|
||||
midgroundForeground: readableOn(seed.colors.midground ?? accent),
|
||||
destructive: '#b94a3a',
|
||||
destructiveForeground: '#ffffff',
|
||||
sidebarBackground: mix('#fafafa', accent, 0.05),
|
||||
@@ -220,6 +225,11 @@ function applyTheme(theme: DesktopTheme, mode: 'light' | 'dark') {
|
||||
root.dataset.hermesTheme = skinNameFromTheme(theme, mode)
|
||||
root.classList.toggle('dark', rendered === 'dark')
|
||||
|
||||
// Brand-accent stroke layer. Falls back to ring when the theme doesn't
|
||||
// declare its own midground, so existing/custom themes keep working.
|
||||
const midground = c.midground ?? c.ring
|
||||
const midgroundForeground = c.midgroundForeground ?? readableOn(midground)
|
||||
|
||||
const vars: Record<string, string> = {
|
||||
'--dt-background': c.background,
|
||||
'--dt-foreground': c.foreground,
|
||||
@@ -238,6 +248,8 @@ function applyTheme(theme: DesktopTheme, mode: 'light' | 'dark') {
|
||||
'--dt-border': c.border,
|
||||
'--dt-input': c.input,
|
||||
'--dt-ring': c.ring,
|
||||
'--dt-midground': midground,
|
||||
'--dt-midground-foreground': midgroundForeground,
|
||||
'--dt-destructive': c.destructive,
|
||||
'--dt-destructive-foreground': c.destructiveForeground,
|
||||
'--dt-sidebar-bg': c.sidebarBackground ?? c.background,
|
||||
|
||||
@@ -51,6 +51,7 @@ export const nousLightTheme: DesktopTheme = {
|
||||
border: '#E3DDCF',
|
||||
input: '#D8D1C3',
|
||||
ring: '#A0782A',
|
||||
midground: '#A0782A',
|
||||
destructive: '#b94a3a',
|
||||
destructiveForeground: '#ffffff',
|
||||
sidebarBackground: '#F5F2EC',
|
||||
@@ -74,6 +75,7 @@ export const hermesGoldTheme: DesktopTheme = {
|
||||
accent: '#fbf3d4',
|
||||
accentForeground: '#5a4310',
|
||||
ring: '#d4af37',
|
||||
midground: '#d4af37',
|
||||
userBubble: '#f6efd5'
|
||||
}
|
||||
}
|
||||
@@ -103,6 +105,7 @@ export const nousTheme: DesktopTheme = {
|
||||
border: `color-mix(in srgb, ${NOUS_LENS_BLUE} 22%, transparent)`,
|
||||
input: `color-mix(in srgb, ${NOUS_LENS_BLUE} 30%, transparent)`,
|
||||
ring: NOUS_LENS_BLUE,
|
||||
midground: NOUS_LENS_BLUE,
|
||||
destructive: '#C72E4D',
|
||||
destructiveForeground: '#FFFFFF',
|
||||
sidebarBackground: `color-mix(in srgb, ${NOUS_LENS_BLUE} 2.5%, #FFFFFF)`,
|
||||
@@ -140,6 +143,7 @@ export const defaultTheme: DesktopTheme = {
|
||||
border: '#1e3232',
|
||||
input: '#1e3232',
|
||||
ring: '#6bbfb5',
|
||||
midground: '#6bbfb5',
|
||||
destructive: '#c0473a',
|
||||
destructiveForeground: '#fef2f2',
|
||||
sidebarBackground: '#0a1616',
|
||||
@@ -172,6 +176,7 @@ export const midnightTheme: DesktopTheme = {
|
||||
border: '#1e1e52',
|
||||
input: '#1e1e52',
|
||||
ring: '#8b80e8',
|
||||
midground: '#8b80e8',
|
||||
destructive: '#b03060',
|
||||
destructiveForeground: '#fef2f2',
|
||||
sidebarBackground: '#06061a',
|
||||
@@ -208,6 +213,7 @@ export const emberTheme: DesktopTheme = {
|
||||
border: '#3a1c08',
|
||||
input: '#3a1c08',
|
||||
ring: '#d97316',
|
||||
midground: '#d97316',
|
||||
destructive: '#c43010',
|
||||
destructiveForeground: '#fef2f2',
|
||||
sidebarBackground: '#100600',
|
||||
@@ -244,6 +250,7 @@ export const monoTheme: DesktopTheme = {
|
||||
border: '#2a2a2a',
|
||||
input: '#2a2a2a',
|
||||
ring: '#9a9a9a',
|
||||
midground: '#9a9a9a',
|
||||
destructive: '#a84040',
|
||||
destructiveForeground: '#fef2f2',
|
||||
sidebarBackground: '#0a0a0a',
|
||||
@@ -276,6 +283,7 @@ export const cyberpunkTheme: DesktopTheme = {
|
||||
border: '#003000',
|
||||
input: '#003000',
|
||||
ring: '#00ff41',
|
||||
midground: '#00ff41',
|
||||
destructive: '#ff003c',
|
||||
destructiveForeground: '#000a00',
|
||||
sidebarBackground: '#000600',
|
||||
@@ -312,6 +320,7 @@ export const slateTheme: DesktopTheme = {
|
||||
border: '#30363d',
|
||||
input: '#30363d',
|
||||
ring: '#58a6ff',
|
||||
midground: '#58a6ff',
|
||||
destructive: '#cf4848',
|
||||
destructiveForeground: '#fef2f2',
|
||||
sidebarBackground: '#090d13',
|
||||
|
||||
@@ -49,6 +49,17 @@ export interface DesktopThemeColors {
|
||||
input: string
|
||||
/** Focus ring / primary accent tint. Also `text-ring` in action bars etc. */
|
||||
ring: string
|
||||
/**
|
||||
* Brand-accent stroke layer. Distinct from `primary` (CTA fill) — this is
|
||||
* the "this thing is alive / live / signal" color used on focus rings,
|
||||
* streaming cursors, the active session pill, branded scrollbars, and text
|
||||
* selection. Falls back to `ring` when omitted. Aliased to the DS
|
||||
* `--midground` token so `@nous-research/ui` components inherit the
|
||||
* desktop's active theme without further wiring.
|
||||
*/
|
||||
midground?: string
|
||||
/** Text on `midground` fills (badges etc). Auto-derived from luminance when omitted. */
|
||||
midgroundForeground?: string
|
||||
/** Destructive action (delete, error). */
|
||||
destructive: string
|
||||
/** Text on destructive. */
|
||||
|
||||
Reference in New Issue
Block a user