| 1 | import { isThemeStyle, type ThemeStyle } from "./theme"; |
| 2 | import { themePackKind, type ThemePackView } from "./themePack"; |
| 3 | |
| 4 | export type ThemePreviewMode = "light" | "dark"; |
| 5 | |
| 6 | export type ThemePreviewPalette = { |
| 7 | bg: string; |
| 8 | bgSoft: string; |
| 9 | panel: string; |
| 10 | sidebar: string; |
| 11 | fg: string; |
| 12 | fgDim: string; |
| 13 | accent: string; |
| 14 | accentFg: string; |
| 15 | border: string; |
| 16 | radius: string; |
| 17 | }; |
| 18 | |
| 19 | /** |
| 20 | * Canonical miniature palettes for the six native appearance directions. |
| 21 | * These mirror the semantic variables in styles.css so every gallery surface |
| 22 | * previews the selected base style instead of falling back to Graphite. |
| 23 | */ |
| 24 | export const BASE_STYLE_PREVIEW_PALETTES: Record<ThemeStyle, Record<ThemePreviewMode, ThemePreviewPalette>> = { |
| 25 | graphite: { |
| 26 | dark: { bg: "#0c0d10", bgSoft: "#101115", panel: "#15161a", sidebar: "#15161a", fg: "#f1f1ef", fgDim: "#a7a8ad", accent: "#ff6a3d", accentFg: "#0c0d10", border: "rgba(255, 255, 255, 0.1)", radius: "8px" }, |
| 27 | light: { bg: "#f4f3ef", bgSoft: "#f0efe9", panel: "#ffffff", sidebar: "#ffffff", fg: "#16181d", fgDim: "#4a4d56", accent: "#ff5a2c", accentFg: "#ffffff", border: "rgba(20, 22, 28, 0.12)", radius: "8px" }, |
| 28 | }, |
| 29 | aurora: { |
| 30 | dark: { bg: "#0e0d18", bgSoft: "#121120", panel: "#17162a", sidebar: "#17162a", fg: "#ecebf7", fgDim: "#a9a4c6", accent: "#8b7cff", accentFg: "#0e0d18", border: "rgba(255, 255, 255, 0.07)", radius: "15px" }, |
| 31 | light: { bg: "#f6f3fb", bgSoft: "#efeaf8", panel: "#fdfcff", sidebar: "#fdfcff", fg: "#1c1830", fgDim: "#574f70", accent: "#6d5efc", accentFg: "#ffffff", border: "rgba(40, 22, 84, 0.09)", radius: "15px" }, |
| 32 | }, |
| 33 | slate: { |
| 34 | dark: { bg: "#0d0f12", bgSoft: "#0f1216", panel: "#15181d", sidebar: "#15181d", fg: "#e7eaf0", fgDim: "#9aa2b1", accent: "#4d8df6", accentFg: "#061129", border: "rgba(255, 255, 255, 0.08)", radius: "12px" }, |
| 35 | light: { bg: "#f5f6f9", bgSoft: "#eef0f4", panel: "#ffffff", sidebar: "#ffffff", fg: "#15181f", fgDim: "#4a5160", accent: "#2f6fe0", accentFg: "#ffffff", border: "rgba(20, 28, 46, 0.1)", radius: "12px" }, |
| 36 | }, |
| 37 | carbon: { |
| 38 | dark: { bg: "#0e0d0c", bgSoft: "#100f0e", panel: "#171614", sidebar: "#171614", fg: "#ede9e3", fgDim: "#a59f95", accent: "#2dd4bf", accentFg: "#001a16", border: "rgba(255, 250, 240, 0.08)", radius: "10px" }, |
| 39 | light: { bg: "#f6f4f0", bgSoft: "#efece6", panel: "#ffffff", sidebar: "#ffffff", fg: "#1a1714", fgDim: "#544e46", accent: "#0d9488", accentFg: "#ffffff", border: "rgba(30, 26, 20, 0.1)", radius: "10px" }, |
| 40 | }, |
| 41 | nocturne: { |
| 42 | dark: { bg: "#101019", bgSoft: "#13131e", panel: "#191a27", sidebar: "#191a27", fg: "#eceaf3", fgDim: "#a6a2bd", accent: "#818cf8", accentFg: "#0d1024", border: "rgba(255, 255, 255, 0.08)", radius: "16px" }, |
| 43 | light: { bg: "#f6f5fb", bgSoft: "#efedf7", panel: "#fdfcff", sidebar: "#fdfcff", fg: "#1b1830", fgDim: "#544f6e", accent: "#6366f1", accentFg: "#ffffff", border: "rgba(40, 30, 80, 0.09)", radius: "16px" }, |
| 44 | }, |
| 45 | amber: { |
| 46 | dark: { bg: "#090a0c", bgSoft: "#111319", panel: "#191b22", sidebar: "#0c0e12", fg: "#f4f5f7", fgDim: "#c0c4cc", accent: "#d4632f", accentFg: "#1a0a04", border: "#343945", radius: "8px" }, |
| 47 | light: { bg: "#f7f8fb", bgSoft: "#eef2f7", panel: "#ffffff", sidebar: "#f3f6fa", fg: "#111827", fgDim: "#4b5563", accent: "#dd5b28", accentFg: "#ffffff", border: "#d8dee8", radius: "8px" }, |
| 48 | }, |
| 49 | }; |
| 50 | |
| 51 | export function baseStyleForPreview(pack: ThemePackView | null): ThemeStyle { |
| 52 | if (isThemeStyle(pack?.baseStyle)) return pack.baseStyle; |
| 53 | if (isThemeStyle(pack?.id)) return pack.id; |
| 54 | return "graphite"; |
| 55 | } |
| 56 | |
| 57 | export function themePreviewPalette(pack: ThemePackView | null, mode: ThemePreviewMode): ThemePreviewPalette { |
| 58 | const base = baseStyleForPreview(pack); |
| 59 | const basePalette = BASE_STYLE_PREVIEW_PALETTES[base][mode]; |
| 60 | if (!pack || themePackKind(pack) === "base") return basePalette; |
| 61 | |
| 62 | const tokens = mode === "light" ? pack.tokens?.light : pack.tokens?.dark; |
| 63 | return { |
| 64 | bg: tokens?.bg || basePalette.bg, |
| 65 | bgSoft: tokens?.bgSoft || basePalette.bgSoft, |
| 66 | panel: tokens?.panel || tokens?.bgElev || basePalette.panel, |
| 67 | sidebar: tokens?.sidebar || basePalette.sidebar, |
| 68 | fg: tokens?.fg || basePalette.fg, |
| 69 | fgDim: tokens?.fgDim || basePalette.fgDim, |
| 70 | accent: tokens?.accent || basePalette.accent, |
| 71 | accentFg: tokens?.accentFg || basePalette.accentFg, |
| 72 | border: tokens?.border || basePalette.border, |
| 73 | radius: basePalette.radius, |
| 74 | }; |
| 75 | } |
| 76 |