feat(app): CSS-variable theming with dark/light palettes and accents
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
+86
-17
@@ -2,23 +2,23 @@ import type { SurfaceState } from "./layoutTypes";
|
||||
|
||||
/** Design tokens — mirror of DOCS/space-sh.pen variables. Single source for the UI. */
|
||||
export const COLORS = {
|
||||
accent: "#4C8DFF",
|
||||
bgApp: "#0E1116",
|
||||
bgElevated: "#1A2029",
|
||||
bgHover: "#222A35",
|
||||
bgPanel: "#0A0D12",
|
||||
bgSidebar: "#13171F",
|
||||
borderStrong: "#323C49",
|
||||
borderSubtle: "#232A33",
|
||||
textPrimary: "#E6EDF3",
|
||||
textSecondary: "#8B97A6",
|
||||
textMuted: "#5A6573",
|
||||
stWork: "#4C8DFF",
|
||||
stWait: "#F2B84B",
|
||||
stDone: "#3FB950",
|
||||
stError: "#F4544E",
|
||||
stIdle: "#5A6573",
|
||||
searchMatch: "#5A4A1F",
|
||||
accent: "var(--c-accent)",
|
||||
bgApp: "var(--c-bg-app)",
|
||||
bgElevated: "var(--c-bg-elevated)",
|
||||
bgHover: "var(--c-bg-hover)",
|
||||
bgPanel: "var(--c-bg-panel)",
|
||||
bgSidebar: "var(--c-bg-sidebar)",
|
||||
borderStrong: "var(--c-border-strong)",
|
||||
borderSubtle: "var(--c-border-subtle)",
|
||||
textPrimary: "var(--c-text-primary)",
|
||||
textSecondary: "var(--c-text-secondary)",
|
||||
textMuted: "var(--c-text-muted)",
|
||||
stWork: "var(--c-st-work)",
|
||||
stWait: "var(--c-st-wait)",
|
||||
stDone: "var(--c-st-done)",
|
||||
stError: "var(--c-st-error)",
|
||||
stIdle: "var(--c-st-idle)",
|
||||
searchMatch: "var(--c-search-match)",
|
||||
} as const;
|
||||
|
||||
export const FONT = {
|
||||
@@ -35,3 +35,72 @@ export const STATE_COLOR: Record<SurfaceState | "stopped", string> = {
|
||||
idle: COLORS.stIdle,
|
||||
stopped: COLORS.stIdle,
|
||||
};
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Palettes
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
type Palette = Record<string, string>;
|
||||
|
||||
/** Dark palette — hex values identical to what COLORS contained before. */
|
||||
const DARK: Palette = {
|
||||
"bg-app": "#0E1116",
|
||||
"bg-elevated": "#1A2029",
|
||||
"bg-hover": "#222A35",
|
||||
"bg-panel": "#0A0D12",
|
||||
"bg-sidebar": "#13171F",
|
||||
"border-strong": "#323C49",
|
||||
"border-subtle": "#232A33",
|
||||
"text-primary": "#E6EDF3",
|
||||
"text-secondary": "#8B97A6",
|
||||
"text-muted": "#5A6573",
|
||||
"st-work": "#4C8DFF",
|
||||
"st-wait": "#F2B84B",
|
||||
"st-done": "#3FB950",
|
||||
"st-error": "#F4544E",
|
||||
"st-idle": "#5A6573",
|
||||
"search-match": "#5A4A1F",
|
||||
};
|
||||
|
||||
/** Light palette — a readable counterpart for every token. */
|
||||
const LIGHT: Palette = {
|
||||
"bg-app": "#F5F7FA",
|
||||
"bg-elevated": "#FFFFFF",
|
||||
"bg-hover": "#E8EDF3",
|
||||
"bg-panel": "#EBEEF3",
|
||||
"bg-sidebar": "#DDE3EC",
|
||||
"border-strong": "#B0BAC7",
|
||||
"border-subtle": "#CDD4DE",
|
||||
"text-primary": "#0D1117",
|
||||
"text-secondary": "#4A5568",
|
||||
"text-muted": "#8898AA",
|
||||
"st-work": "#2266CC",
|
||||
"st-wait": "#C07800",
|
||||
"st-done": "#1A7A30",
|
||||
"st-error": "#C4231F",
|
||||
"st-idle": "#8898AA",
|
||||
"search-match": "#FDE68A",
|
||||
};
|
||||
|
||||
export const ACCENTS: Record<string, string> = {
|
||||
blue: "#4C8DFF",
|
||||
teal: "#34D3C2",
|
||||
purple: "#9B7BFF",
|
||||
green: "#3FB950",
|
||||
orange: "#F2934B",
|
||||
};
|
||||
|
||||
export type ThemeName = "dark" | "light";
|
||||
|
||||
/** Real color values for consumers that can't use var() (xterm). Keys are the kebab tokens plus "accent". */
|
||||
export function resolvePalette(theme: ThemeName, accent: string): Record<string, string> {
|
||||
const base = theme === "light" ? LIGHT : DARK;
|
||||
return { ...base, accent: ACCENTS[accent] ?? ACCENTS.blue };
|
||||
}
|
||||
|
||||
/** Write the active palette to :root as --c-* custom properties. */
|
||||
export function applyTheme(theme: ThemeName, accent: string): void {
|
||||
const p = resolvePalette(theme, accent);
|
||||
const root = document.documentElement.style;
|
||||
for (const [k, v] of Object.entries(p)) root.setProperty(`--c-${k}`, v);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user