diff --git a/AGENTS.md b/AGENTS.md index cc7846df..2f71f2d3 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -121,6 +121,8 @@ After changing an action name, parameter, result description/schema, example or SDK breaking changes also update [CHANGELOG.md](packages/sdk/CHANGELOG.md) and [VERSIONING.md](packages/sdk/VERSIONING.md). WebUI changes follow its [interaction conventions](packages/webui/README.md). Keep user-facing documentation aligned with behavior. +Standalone WebUI branding uses the [SnowLuma mascot](assets/readme/mascot.png) and a lavender default accent. Keep server defaults, frontend presets and pre-mount CSS aligned as described in [WebUI default appearance](packages/webui/README.md#default-appearance), while preserving saved user choices and host appearance overlays. + The root [README.md](README.md) presents the project's purpose, overall capabilities, quick start and documentation entry points. Update it only when those overview details change; adding or fixing an individual feature does not justify adding a dedicated section there. Put feature-specific API usage, configuration, limitations and troubleshooting in the relevant package README or topic document, preferring existing documentation. Edit sources rather than `dist` outputs. Native artifacts in `packages/runtime/native` are supplied build inputs; do not substitute arbitrary local binaries to make a build pass. Packaging changes must preserve the checks in [Core's build configuration](packages/core/vite.config.ts) and [the release layout validator](tools/check-release-layout.mjs). diff --git a/assets/brand/mascot-avatar.png b/assets/brand/mascot-avatar.png new file mode 100644 index 00000000..557bee74 Binary files /dev/null and b/assets/brand/mascot-avatar.png differ diff --git a/packages/core/src/webui/ui-config.ts b/packages/core/src/webui/ui-config.ts index 63ec06ba..8cd3539f 100644 --- a/packages/core/src/webui/ui-config.ts +++ b/packages/core/src/webui/ui-config.ts @@ -44,7 +44,7 @@ export type SidebarStyle = 'follow' | 'panel' | 'accent'; export type BackgroundType = 'none' | 'solid' | 'gradient' | 'image'; export type Density = 'cozy' | 'compact'; export type TimeFormat = '12h' | '24h'; -/** Full color scheme. 'default' keeps the sky theme (driven by `mode`); the +/** Full color scheme. 'default' keeps the lavender theme (driven by `mode`); the * Catppuccin flavors are complete palettes that also fix light/dark. */ export type Palette = | 'default' @@ -85,7 +85,7 @@ export interface UiAppearance { accentCustom: string; accentScope: AccentScope; darkIntensity: DarkIntensity; - /** Full color scheme; 'default' = the built-in sky theme. */ + /** Full color scheme; 'default' = the built-in lavender theme. */ palette: Palette; sidebarStyle: SidebarStyle; background: UiBackground; @@ -203,12 +203,12 @@ export interface UiConfig { } // ─── Defaults ──────────────────────────────────────────────────────────── -// Mirror the pre-existing ThemeContext defaults so an upgrade is a no-op -// visually until the operator changes something. +// Keep these defaults aligned with ThemeContext. Saved appearance choices +// are normalized independently and remain the operator's preference. const DEFAULT_BACKGROUND: UiBackground = { type: 'none', - color: '#0ea5e9', + color: '#b99ae6', gradient: 'none', imageOpacity: 0.15, imageBlur: 0, @@ -220,8 +220,8 @@ const DEFAULT_BACKGROUND: UiBackground = { const DEFAULT_APPEARANCE: UiAppearance = { mode: 'system', accentMode: 'preset', - accentPreset: 'sky', - accentCustom: '#38bdf8', + accentPreset: 'lavender', + accentCustom: '#8561bd', accentScope: 'global', darkIntensity: 'soft', palette: 'default', diff --git a/packages/webui/README.md b/packages/webui/README.md index d84dd902..9c3580be 100644 --- a/packages/webui/README.md +++ b/packages/webui/README.md @@ -3,6 +3,23 @@ SnowLuma's browser console is a Vite + React application for managing runtime status, OneBot configuration, logs, storage, and server settings. +## Default appearance + +New installations and appearance resets use the mascot's lavender accent. +The light variant uses a deeper purple for readable button labels; dark mode +uses a softer lavender. Existing saved accents and custom colors are preserved. +The original sky-blue accent remains available in Settings. + +Keep the server defaults in `packages/core/src/webui/ui-config.ts`, the frontend +defaults and preset in `src/contexts/ThemeContext.tsx`, and the pre-mount tokens +in `src/index.css` aligned when changing the default accent. + +The browser favicon, home-screen icon and in-app logo share the mascot avatar +in [`assets/brand/mascot-avatar.png`](../../assets/brand/mascot-avatar.png). +Its exported sizes live in `public/`: `logo.png` (512 px), `favicon.png` (64 px), +and `apple-touch-icon.png` (180 px). Export from the master without redrawing +individual sizes. + ## Host appearance integration `SNOWLUMA_WEBUI_TARGET=maibot` opts a deployment into a reversible millennium diff --git a/packages/webui/index.html b/packages/webui/index.html index 80cc5386..84b7eac4 100644 --- a/packages/webui/index.html +++ b/packages/webui/index.html @@ -2,9 +2,10 @@ - + + - + diff --git a/packages/webui/public/apple-touch-icon.png b/packages/webui/public/apple-touch-icon.png new file mode 100644 index 00000000..d3f4d517 Binary files /dev/null and b/packages/webui/public/apple-touch-icon.png differ diff --git a/packages/webui/public/favicon.png b/packages/webui/public/favicon.png new file mode 100644 index 00000000..b205ca17 Binary files /dev/null and b/packages/webui/public/favicon.png differ diff --git a/packages/webui/public/favicon.svg b/packages/webui/public/favicon.svg deleted file mode 100644 index 6893eb13..00000000 --- a/packages/webui/public/favicon.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/packages/webui/public/logo.png b/packages/webui/public/logo.png index ea437bbb..bb89d10f 100644 Binary files a/packages/webui/public/logo.png and b/packages/webui/public/logo.png differ diff --git a/packages/webui/src/components/layout/sidebar.tsx b/packages/webui/src/components/layout/sidebar.tsx index 287973a7..ee17bd74 100644 --- a/packages/webui/src/components/layout/sidebar.tsx +++ b/packages/webui/src/components/layout/sidebar.tsx @@ -147,7 +147,7 @@ export function Sidebar({ collapsed = false, onItemClick }: SidebarProps) {
- SnowLuma + SnowLuma
- SnowLuma + SnowLuma
diff --git a/packages/webui/src/components/pages/settings-page.tsx b/packages/webui/src/components/pages/settings-page.tsx index e3d92240..a98a1753 100644 --- a/packages/webui/src/components/pages/settings-page.tsx +++ b/packages/webui/src/components/pages/settings-page.tsx @@ -2078,7 +2078,7 @@ function AboutPanel() { SnowLuma
diff --git a/packages/webui/src/contexts/ThemeContext.tsx b/packages/webui/src/contexts/ThemeContext.tsx index 0b8a2106..3813a910 100644 --- a/packages/webui/src/contexts/ThemeContext.tsx +++ b/packages/webui/src/contexts/ThemeContext.tsx @@ -46,7 +46,8 @@ export type AppearancePatch = Partial> & { // ─── Frontend catalogues (the server stores only ids; the visuals live here) ─── -export type AccentColor = 'sky' | 'blue' | 'violet' | 'rose' | 'emerald' | 'amber' | 'orange'; +export type AccentColor = + 'lavender' | 'sky' | 'blue' | 'violet' | 'rose' | 'emerald' | 'amber' | 'orange'; export interface AccentSpec { id: AccentColor; @@ -57,6 +58,13 @@ export interface AccentSpec { } export const ACCENTS: AccentSpec[] = [ + { + id: 'lavender', + label: '薰衣草', + swatch: '#8561bd', + light: { primary: 'oklch(57% 0.14 300)', ring: 'oklch(57% 0.14 300)' }, + dark: { primary: 'oklch(78% 0.115 300)', ring: 'oklch(78% 0.115 300)' }, + }, { id: 'sky', label: '天蓝', @@ -198,15 +206,15 @@ export const UI_SCALE = { min: 0.9, max: 1.2, step: 0.05 } as const; export const DEFAULT_APPEARANCE: UiAppearance = { mode: 'system', accentMode: 'preset', - accentPreset: 'sky', - accentCustom: '#38bdf8', + accentPreset: 'lavender', + accentCustom: '#8561bd', accentScope: 'global', darkIntensity: 'soft', palette: 'default', sidebarStyle: 'follow', background: { type: 'none', - color: '#0ea5e9', + color: '#b99ae6', gradient: 'none', imageOpacity: 0.15, imageBlur: 0, @@ -327,7 +335,7 @@ function accentVarsCss(a: UiAppearance): string { const surf = a.palette === 'default'; if (a.accentMode === 'custom') { - const hex = safeHex(a.accentCustom, '#38bdf8'); + const hex = safeHex(a.accentCustom, DEFAULT_APPEARANCE.accentCustom); const lightFg = readableForeground(hex); // Dark mode: lighten the accent for contrast on dark surfaces, and pick // the foreground from the *lightened* colour (a light accent needs dark text). @@ -590,7 +598,7 @@ export const PALETTE_OPTIONS: PaletteSpec[] = [ { id: 'default', label: '默认', - preview: { bg: '#f1f5f9', surface: '#ffffff', dots: ['#0ea5e9', '#10b981', '#f43f5e'] }, + preview: { bg: '#f1f5f9', surface: '#ffffff', dots: ['#8561bd', '#10b981', '#f43f5e'] }, }, { id: 'catppuccin-latte', diff --git a/packages/webui/src/index.css b/packages/webui/src/index.css index 16e4ebfa..d5b6d5d8 100644 --- a/packages/webui/src/index.css +++ b/packages/webui/src/index.css @@ -4,7 +4,7 @@ @custom-variant dark (&:where(.dark, .dark *)); /* ────────────────────────────────────────────── - Theme tokens (sky-blue accent) + Theme tokens (mascot lavender accent) ────────────────────────────────────────────── */ :root { --radius: 0.75rem; @@ -18,8 +18,8 @@ --popover: oklch(100% 0 0); --popover-foreground: oklch(20% 0.03 250); - /* sky-500 */ - --primary: oklch(68.5% 0.155 230); + /* A deeper lavender keeps light-mode button labels readable. */ + --primary: oklch(57% 0.14 300); --primary-foreground: oklch(99% 0.005 240); --secondary: oklch(96% 0.012 240); @@ -28,8 +28,8 @@ --muted: oklch(96% 0.012 240); --muted-foreground: oklch(50% 0.02 250); - --accent: oklch(94% 0.03 230); - --accent-foreground: oklch(35% 0.07 230); + --accent: oklch(94% 0.03 300); + --accent-foreground: oklch(35% 0.07 300); --destructive: oklch(60% 0.22 27); --destructive-foreground: oklch(99% 0.005 240); @@ -49,16 +49,16 @@ --border: oklch(92% 0.01 240); --input: oklch(94% 0.012 240); - --ring: oklch(68.5% 0.155 230); + --ring: oklch(57% 0.14 300); --sidebar: oklch(94% 0.008 240); --sidebar-foreground: oklch(25% 0.03 250); - --sidebar-primary: oklch(68.5% 0.155 230); + --sidebar-primary: oklch(57% 0.14 300); --sidebar-primary-foreground: oklch(99% 0.005 240); - --sidebar-accent: oklch(90% 0.025 230); - --sidebar-accent-foreground: oklch(35% 0.08 230); + --sidebar-accent: oklch(90% 0.025 300); + --sidebar-accent-foreground: oklch(35% 0.08 300); --sidebar-border: oklch(92% 0.01 240); - --sidebar-ring: oklch(68.5% 0.155 230); + --sidebar-ring: oklch(57% 0.14 300); --media-outline: oklch(0% 0 0 / 0.1); /* Cards need depth without turning every surface into a hard outlined box. @@ -79,7 +79,7 @@ --popover: oklch(20% 0.025 250); --popover-foreground: oklch(96% 0.01 240); - --primary: oklch(75% 0.14 230); + --primary: oklch(78% 0.115 300); --primary-foreground: oklch(15% 0.02 250); --secondary: oklch(25% 0.025 250); @@ -88,8 +88,8 @@ --muted: oklch(24% 0.02 250); --muted-foreground: oklch(68% 0.02 240); - --accent: oklch(28% 0.05 230); - --accent-foreground: oklch(85% 0.1 230); + --accent: oklch(28% 0.05 300); + --accent-foreground: oklch(85% 0.1 300); --destructive: oklch(62% 0.2 27); --destructive-foreground: oklch(98% 0.005 240); @@ -106,16 +106,16 @@ --border: oklch(28% 0.02 250); --input: oklch(26% 0.02 250); - --ring: oklch(75% 0.14 230); + --ring: oklch(78% 0.115 300); --sidebar: oklch(12% 0.018 250); --sidebar-foreground: oklch(92% 0.01 240); - --sidebar-primary: oklch(75% 0.14 230); + --sidebar-primary: oklch(78% 0.115 300); --sidebar-primary-foreground: oklch(15% 0.02 250); - --sidebar-accent: oklch(28% 0.05 230); - --sidebar-accent-foreground: oklch(85% 0.1 230); + --sidebar-accent: oklch(28% 0.05 300); + --sidebar-accent-foreground: oklch(85% 0.1 300); --sidebar-border: oklch(26% 0.02 250); - --sidebar-ring: oklch(75% 0.14 230); + --sidebar-ring: oklch(78% 0.115 300); --media-outline: oklch(100% 0 0 / 0.12); --shadow-card: