This commit is contained in:
1 parent
8efd032cc6
commit
df38dccbf1
735 files changed
+128321
-120870
No files matched your search
+393
-366
@@ -3,56 +3,78 @@
|
||||
|
||||
// Selectable body fonts. Web-safe stacks render with no extra request; the few
|
||||
// Google fonts load via a <link> ThemeVars injects when chosen.
|
||||
export const FONTS: Record<string, { label: string; stack: string; google?: string }> = {
|
||||
nunito: { label: "Nunito (default)", stack: 'var(--font-nunito), "Nunito", sans-serif' },
|
||||
system: { label: "System", stack: 'ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif' },
|
||||
inter: {
|
||||
label: "Inter",
|
||||
stack: '"Inter", sans-serif',
|
||||
google: "Inter:wght@400;600;700;800",
|
||||
},
|
||||
poppins: {
|
||||
label: "Poppins",
|
||||
stack: '"Poppins", sans-serif',
|
||||
google: "Poppins:wght@400;600;700;800",
|
||||
},
|
||||
roboto: { label: "Roboto", stack: '"Roboto", sans-serif', google: "Roboto:wght@400;500;700" },
|
||||
georgia: { label: "Georgia (serif)", stack: 'Georgia, "Times New Roman", serif' },
|
||||
trebuchet: { label: "Trebuchet", stack: '"Trebuchet MS", Verdana, sans-serif' },
|
||||
verdana: { label: "Verdana", stack: "Verdana, Geneva, sans-serif" },
|
||||
comic: { label: "Comic (retro)", stack: '"Comic Sans MS", "Comic Sans", cursive' },
|
||||
mono: { label: "Monospace", stack: '"Courier New", ui-monospace, monospace' },
|
||||
export const FONTS: Record<
|
||||
string,
|
||||
{ label: string; stack: string; google?: string }
|
||||
> = {
|
||||
nunito: {
|
||||
label: "Nunito (default)",
|
||||
stack: 'var(--font-nunito), "Nunito", sans-serif',
|
||||
},
|
||||
system: {
|
||||
label: "System",
|
||||
stack: 'ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif',
|
||||
},
|
||||
inter: {
|
||||
label: "Inter",
|
||||
stack: '"Inter", sans-serif',
|
||||
google: "Inter:wght@400;600;700;800",
|
||||
},
|
||||
poppins: {
|
||||
label: "Poppins",
|
||||
stack: '"Poppins", sans-serif',
|
||||
google: "Poppins:wght@400;600;700;800",
|
||||
},
|
||||
roboto: {
|
||||
label: "Roboto",
|
||||
stack: '"Roboto", sans-serif',
|
||||
google: "Roboto:wght@400;500;700",
|
||||
},
|
||||
georgia: {
|
||||
label: "Georgia (serif)",
|
||||
stack: 'Georgia, "Times New Roman", serif',
|
||||
},
|
||||
trebuchet: {
|
||||
label: "Trebuchet",
|
||||
stack: '"Trebuchet MS", Verdana, sans-serif',
|
||||
},
|
||||
verdana: { label: "Verdana", stack: "Verdana, Geneva, sans-serif" },
|
||||
comic: {
|
||||
label: "Comic (retro)",
|
||||
stack: '"Comic Sans MS", "Comic Sans", cursive',
|
||||
},
|
||||
mono: { label: "Monospace", stack: '"Courier New", ui-monospace, monospace' },
|
||||
};
|
||||
|
||||
// The colour settings ThemeVars injects into :root. Editing these recolours the
|
||||
// whole site live (ThemeVars reads them on every request).
|
||||
export const THEME_COLOR_KEYS = [
|
||||
"color_primary",
|
||||
"color_background",
|
||||
"color_surface",
|
||||
"color_dropdown",
|
||||
"color_navbar",
|
||||
"color_navbar_text",
|
||||
"color_text",
|
||||
"color_text_muted",
|
||||
"color_accent",
|
||||
"color_success",
|
||||
"color_warning",
|
||||
"color_error",
|
||||
"color_info",
|
||||
"button_primary_color",
|
||||
"button_text_color",
|
||||
"button_secondary_color",
|
||||
"button_secondary_text_color",
|
||||
"button_danger_color",
|
||||
"button_danger_text_color",
|
||||
"button_outline_color",
|
||||
"button_outline_text_color",
|
||||
"link_color",
|
||||
"link_hover_color",
|
||||
"border_color",
|
||||
"gradient_from",
|
||||
"gradient_to",
|
||||
"color_primary",
|
||||
"color_background",
|
||||
"color_surface",
|
||||
"color_dropdown",
|
||||
"color_navbar",
|
||||
"color_navbar_text",
|
||||
"color_text",
|
||||
"color_text_muted",
|
||||
"color_accent",
|
||||
"color_success",
|
||||
"color_warning",
|
||||
"color_error",
|
||||
"color_info",
|
||||
"button_primary_color",
|
||||
"button_text_color",
|
||||
"button_secondary_color",
|
||||
"button_secondary_text_color",
|
||||
"button_danger_color",
|
||||
"button_danger_text_color",
|
||||
"button_outline_color",
|
||||
"button_outline_text_color",
|
||||
"link_color",
|
||||
"link_hover_color",
|
||||
"border_color",
|
||||
"gradient_from",
|
||||
"gradient_to",
|
||||
] as const;
|
||||
|
||||
export type ThemeMode = "light" | "dark";
|
||||
@@ -63,341 +85,346 @@ export type ThemePreset = Record<ThemeMode, ThemePalette>;
|
||||
// Curated palettes (faithful to the atom theme presets). Each is a full set of
|
||||
// the colour keys above so applying one fully reskins the site.
|
||||
const LEGACY_PALETTES: Record<string, Partial<ThemePalette>> = {
|
||||
"Atom (golden)": {
|
||||
color_primary: "#f59e0b",
|
||||
color_background: "#f8fafc",
|
||||
color_surface: "#ffffff",
|
||||
color_dropdown: "#ffffff",
|
||||
color_navbar: "#ffffff",
|
||||
color_navbar_text: "#1e293b",
|
||||
color_text: "#0f172a",
|
||||
color_text_muted: "#64748b",
|
||||
color_accent: "#10b981",
|
||||
color_success: "#16a34a",
|
||||
color_warning: "#eab308",
|
||||
color_error: "#ef4444",
|
||||
color_info: "#0ea5e9",
|
||||
button_primary_color: "#f59e0b",
|
||||
button_text_color: "#1e293b",
|
||||
border_color: "#eeb425",
|
||||
},
|
||||
Midnight: {
|
||||
color_primary: "#eeb425",
|
||||
color_background: "#0f1117",
|
||||
color_surface: "#171a21",
|
||||
color_dropdown: "#1f242d",
|
||||
color_navbar: "#171a21",
|
||||
color_navbar_text: "#e5e7eb",
|
||||
color_text: "#e5e7eb",
|
||||
color_text_muted: "#9ca3af",
|
||||
color_accent: "#22c55e",
|
||||
color_success: "#22c55e",
|
||||
color_warning: "#facc15",
|
||||
color_error: "#f87171",
|
||||
color_info: "#38bdf8",
|
||||
button_primary_color: "#eeb425",
|
||||
button_text_color: "#1a1a2e",
|
||||
border_color: "#eeb425",
|
||||
},
|
||||
Ocean: {
|
||||
color_primary: "#0ea5e9",
|
||||
color_background: "#f0f9ff",
|
||||
color_surface: "#ffffff",
|
||||
color_dropdown: "#ffffff",
|
||||
color_navbar: "#ffffff",
|
||||
color_navbar_text: "#0c4a6e",
|
||||
color_text: "#082f49",
|
||||
color_text_muted: "#64748b",
|
||||
color_accent: "#14b8a6",
|
||||
color_success: "#16a34a",
|
||||
color_warning: "#eab308",
|
||||
color_error: "#ef4444",
|
||||
color_info: "#0ea5e9",
|
||||
button_primary_color: "#0ea5e9",
|
||||
button_text_color: "#ffffff",
|
||||
border_color: "#38bdf8",
|
||||
},
|
||||
Forest: {
|
||||
color_primary: "#16a34a",
|
||||
color_background: "#f3faf4",
|
||||
color_surface: "#ffffff",
|
||||
color_dropdown: "#ffffff",
|
||||
color_navbar: "#ffffff",
|
||||
color_navbar_text: "#14532d",
|
||||
color_text: "#052e16",
|
||||
color_text_muted: "#5f6b63",
|
||||
color_accent: "#84cc16",
|
||||
color_success: "#16a34a",
|
||||
color_warning: "#eab308",
|
||||
color_error: "#ef4444",
|
||||
color_info: "#0ea5e9",
|
||||
button_primary_color: "#16a34a",
|
||||
button_text_color: "#ffffff",
|
||||
border_color: "#22c55e",
|
||||
},
|
||||
Sunset: {
|
||||
color_primary: "#f97316",
|
||||
color_background: "#fff7ed",
|
||||
color_surface: "#ffffff",
|
||||
color_dropdown: "#ffffff",
|
||||
color_navbar: "#ffffff",
|
||||
color_navbar_text: "#7c2d12",
|
||||
color_text: "#431407",
|
||||
color_text_muted: "#78716c",
|
||||
color_accent: "#ec4899",
|
||||
color_success: "#16a34a",
|
||||
color_warning: "#eab308",
|
||||
color_error: "#ef4444",
|
||||
color_info: "#0ea5e9",
|
||||
button_primary_color: "#f97316",
|
||||
button_text_color: "#ffffff",
|
||||
border_color: "#fb923c",
|
||||
},
|
||||
Candy: {
|
||||
color_primary: "#ec4899",
|
||||
color_background: "#fdf2f8",
|
||||
color_surface: "#ffffff",
|
||||
color_dropdown: "#ffffff",
|
||||
color_navbar: "#ffffff",
|
||||
color_navbar_text: "#831843",
|
||||
color_text: "#500724",
|
||||
color_text_muted: "#9d6b80",
|
||||
color_accent: "#a855f7",
|
||||
color_success: "#16a34a",
|
||||
color_warning: "#eab308",
|
||||
color_error: "#ef4444",
|
||||
color_info: "#0ea5e9",
|
||||
button_primary_color: "#ec4899",
|
||||
button_text_color: "#ffffff",
|
||||
border_color: "#f472b6",
|
||||
},
|
||||
Galaxy: {
|
||||
color_primary: "#a855f7",
|
||||
color_background: "#0b0a1f",
|
||||
color_surface: "#171430",
|
||||
color_dropdown: "#211d44",
|
||||
color_navbar: "#171430",
|
||||
color_navbar_text: "#e9e5ff",
|
||||
color_text: "#e9e5ff",
|
||||
color_text_muted: "#a39dcf",
|
||||
color_accent: "#22d3ee",
|
||||
color_success: "#22c55e",
|
||||
color_warning: "#facc15",
|
||||
color_error: "#f87171",
|
||||
color_info: "#38bdf8",
|
||||
button_primary_color: "#a855f7",
|
||||
button_text_color: "#ffffff",
|
||||
border_color: "#7c3aed",
|
||||
},
|
||||
Royal: {
|
||||
color_primary: "#4f46e5",
|
||||
color_background: "#f5f6ff",
|
||||
color_surface: "#ffffff",
|
||||
color_dropdown: "#ffffff",
|
||||
color_navbar: "#ffffff",
|
||||
color_navbar_text: "#1e1b4b",
|
||||
color_text: "#1e1b4b",
|
||||
color_text_muted: "#636681",
|
||||
color_accent: "#d97706",
|
||||
color_success: "#16a34a",
|
||||
color_warning: "#eab308",
|
||||
color_error: "#ef4444",
|
||||
color_info: "#0ea5e9",
|
||||
button_primary_color: "#4f46e5",
|
||||
button_text_color: "#ffffff",
|
||||
border_color: "#818cf8",
|
||||
},
|
||||
Cyberpunk: {
|
||||
color_primary: "#f0db4f",
|
||||
color_background: "#0d0221",
|
||||
color_surface: "#190933",
|
||||
color_dropdown: "#241046",
|
||||
color_navbar: "#190933",
|
||||
color_navbar_text: "#f0db4f",
|
||||
color_text: "#f5e9ff",
|
||||
color_text_muted: "#b08fd6",
|
||||
color_accent: "#ff2a6d",
|
||||
color_success: "#22c55e",
|
||||
color_warning: "#facc15",
|
||||
color_error: "#f87171",
|
||||
color_info: "#38bdf8",
|
||||
button_primary_color: "#ff2a6d",
|
||||
button_text_color: "#ffffff",
|
||||
border_color: "#05d9e8",
|
||||
},
|
||||
Neon: {
|
||||
color_primary: "#39ff14",
|
||||
color_background: "#0a0a0a",
|
||||
color_surface: "#141414",
|
||||
color_dropdown: "#1d1d1d",
|
||||
color_navbar: "#141414",
|
||||
color_navbar_text: "#39ff14",
|
||||
color_text: "#e8ffe8",
|
||||
color_text_muted: "#7fae7f",
|
||||
color_accent: "#ff00ff",
|
||||
color_success: "#22c55e",
|
||||
color_warning: "#facc15",
|
||||
color_error: "#f87171",
|
||||
color_info: "#38bdf8",
|
||||
button_primary_color: "#39ff14",
|
||||
button_text_color: "#0a0a0a",
|
||||
border_color: "#39ff14",
|
||||
},
|
||||
Coffee: {
|
||||
color_primary: "#a16207",
|
||||
color_background: "#f5efe6",
|
||||
color_surface: "#fffaf2",
|
||||
color_dropdown: "#fffaf2",
|
||||
color_navbar: "#fffaf2",
|
||||
color_navbar_text: "#3f2d1c",
|
||||
color_text: "#3f2d1c",
|
||||
color_text_muted: "#8a7560",
|
||||
color_accent: "#15803d",
|
||||
color_success: "#16a34a",
|
||||
color_warning: "#eab308",
|
||||
color_error: "#ef4444",
|
||||
color_info: "#0ea5e9",
|
||||
button_primary_color: "#a16207",
|
||||
button_text_color: "#ffffff",
|
||||
border_color: "#ca8a04",
|
||||
},
|
||||
Arctic: {
|
||||
color_primary: "#0891b2",
|
||||
color_background: "#eef6fb",
|
||||
color_surface: "#ffffff",
|
||||
color_dropdown: "#ffffff",
|
||||
color_navbar: "#ffffff",
|
||||
color_navbar_text: "#0e3a4f",
|
||||
color_text: "#0e3a4f",
|
||||
color_text_muted: "#5b7585",
|
||||
color_accent: "#6366f1",
|
||||
color_success: "#16a34a",
|
||||
color_warning: "#eab308",
|
||||
color_error: "#ef4444",
|
||||
color_info: "#0ea5e9",
|
||||
button_primary_color: "#0891b2",
|
||||
button_text_color: "#ffffff",
|
||||
border_color: "#67e8f9",
|
||||
},
|
||||
Christmas: {
|
||||
color_primary: "#dc2626",
|
||||
color_background: "#f4faf4",
|
||||
color_surface: "#ffffff",
|
||||
color_dropdown: "#ffffff",
|
||||
color_navbar: "#0f3d24",
|
||||
color_navbar_text: "#ffffff",
|
||||
color_text: "#14321f",
|
||||
color_text_muted: "#5f7a68",
|
||||
color_accent: "#15803d",
|
||||
color_success: "#22c55e",
|
||||
color_warning: "#eab308",
|
||||
color_error: "#ef4444",
|
||||
color_info: "#0ea5e9",
|
||||
button_primary_color: "#dc2626",
|
||||
button_text_color: "#ffffff",
|
||||
border_color: "#16a34a",
|
||||
},
|
||||
Dusk: {
|
||||
color_primary: "#e8a33d",
|
||||
color_background: "#1b2230",
|
||||
color_surface: "#232c3d",
|
||||
color_dropdown: "#2b3548",
|
||||
color_navbar: "#232c3d",
|
||||
color_navbar_text: "#dfe5ef",
|
||||
color_text: "#dfe5ef",
|
||||
color_text_muted: "#94a0b5",
|
||||
color_accent: "#5eb0c9",
|
||||
color_success: "#22c55e",
|
||||
color_warning: "#facc15",
|
||||
color_error: "#f87171",
|
||||
color_info: "#38bdf8",
|
||||
button_primary_color: "#e8a33d",
|
||||
button_text_color: "#1b2230",
|
||||
border_color: "#e8a33d",
|
||||
},
|
||||
"Atom (golden)": {
|
||||
color_primary: "#f59e0b",
|
||||
color_background: "#f8fafc",
|
||||
color_surface: "#ffffff",
|
||||
color_dropdown: "#ffffff",
|
||||
color_navbar: "#ffffff",
|
||||
color_navbar_text: "#1e293b",
|
||||
color_text: "#0f172a",
|
||||
color_text_muted: "#64748b",
|
||||
color_accent: "#10b981",
|
||||
color_success: "#16a34a",
|
||||
color_warning: "#eab308",
|
||||
color_error: "#ef4444",
|
||||
color_info: "#0ea5e9",
|
||||
button_primary_color: "#f59e0b",
|
||||
button_text_color: "#1e293b",
|
||||
border_color: "#eeb425",
|
||||
},
|
||||
Midnight: {
|
||||
color_primary: "#eeb425",
|
||||
color_background: "#0f1117",
|
||||
color_surface: "#171a21",
|
||||
color_dropdown: "#1f242d",
|
||||
color_navbar: "#171a21",
|
||||
color_navbar_text: "#e5e7eb",
|
||||
color_text: "#e5e7eb",
|
||||
color_text_muted: "#9ca3af",
|
||||
color_accent: "#22c55e",
|
||||
color_success: "#22c55e",
|
||||
color_warning: "#facc15",
|
||||
color_error: "#f87171",
|
||||
color_info: "#38bdf8",
|
||||
button_primary_color: "#eeb425",
|
||||
button_text_color: "#1a1a2e",
|
||||
border_color: "#eeb425",
|
||||
},
|
||||
Ocean: {
|
||||
color_primary: "#0ea5e9",
|
||||
color_background: "#f0f9ff",
|
||||
color_surface: "#ffffff",
|
||||
color_dropdown: "#ffffff",
|
||||
color_navbar: "#ffffff",
|
||||
color_navbar_text: "#0c4a6e",
|
||||
color_text: "#082f49",
|
||||
color_text_muted: "#64748b",
|
||||
color_accent: "#14b8a6",
|
||||
color_success: "#16a34a",
|
||||
color_warning: "#eab308",
|
||||
color_error: "#ef4444",
|
||||
color_info: "#0ea5e9",
|
||||
button_primary_color: "#0ea5e9",
|
||||
button_text_color: "#ffffff",
|
||||
border_color: "#38bdf8",
|
||||
},
|
||||
Forest: {
|
||||
color_primary: "#16a34a",
|
||||
color_background: "#f3faf4",
|
||||
color_surface: "#ffffff",
|
||||
color_dropdown: "#ffffff",
|
||||
color_navbar: "#ffffff",
|
||||
color_navbar_text: "#14532d",
|
||||
color_text: "#052e16",
|
||||
color_text_muted: "#5f6b63",
|
||||
color_accent: "#84cc16",
|
||||
color_success: "#16a34a",
|
||||
color_warning: "#eab308",
|
||||
color_error: "#ef4444",
|
||||
color_info: "#0ea5e9",
|
||||
button_primary_color: "#16a34a",
|
||||
button_text_color: "#ffffff",
|
||||
border_color: "#22c55e",
|
||||
},
|
||||
Sunset: {
|
||||
color_primary: "#f97316",
|
||||
color_background: "#fff7ed",
|
||||
color_surface: "#ffffff",
|
||||
color_dropdown: "#ffffff",
|
||||
color_navbar: "#ffffff",
|
||||
color_navbar_text: "#7c2d12",
|
||||
color_text: "#431407",
|
||||
color_text_muted: "#78716c",
|
||||
color_accent: "#ec4899",
|
||||
color_success: "#16a34a",
|
||||
color_warning: "#eab308",
|
||||
color_error: "#ef4444",
|
||||
color_info: "#0ea5e9",
|
||||
button_primary_color: "#f97316",
|
||||
button_text_color: "#ffffff",
|
||||
border_color: "#fb923c",
|
||||
},
|
||||
Candy: {
|
||||
color_primary: "#ec4899",
|
||||
color_background: "#fdf2f8",
|
||||
color_surface: "#ffffff",
|
||||
color_dropdown: "#ffffff",
|
||||
color_navbar: "#ffffff",
|
||||
color_navbar_text: "#831843",
|
||||
color_text: "#500724",
|
||||
color_text_muted: "#9d6b80",
|
||||
color_accent: "#a855f7",
|
||||
color_success: "#16a34a",
|
||||
color_warning: "#eab308",
|
||||
color_error: "#ef4444",
|
||||
color_info: "#0ea5e9",
|
||||
button_primary_color: "#ec4899",
|
||||
button_text_color: "#ffffff",
|
||||
border_color: "#f472b6",
|
||||
},
|
||||
Galaxy: {
|
||||
color_primary: "#a855f7",
|
||||
color_background: "#0b0a1f",
|
||||
color_surface: "#171430",
|
||||
color_dropdown: "#211d44",
|
||||
color_navbar: "#171430",
|
||||
color_navbar_text: "#e9e5ff",
|
||||
color_text: "#e9e5ff",
|
||||
color_text_muted: "#a39dcf",
|
||||
color_accent: "#22d3ee",
|
||||
color_success: "#22c55e",
|
||||
color_warning: "#facc15",
|
||||
color_error: "#f87171",
|
||||
color_info: "#38bdf8",
|
||||
button_primary_color: "#a855f7",
|
||||
button_text_color: "#ffffff",
|
||||
border_color: "#7c3aed",
|
||||
},
|
||||
Royal: {
|
||||
color_primary: "#4f46e5",
|
||||
color_background: "#f5f6ff",
|
||||
color_surface: "#ffffff",
|
||||
color_dropdown: "#ffffff",
|
||||
color_navbar: "#ffffff",
|
||||
color_navbar_text: "#1e1b4b",
|
||||
color_text: "#1e1b4b",
|
||||
color_text_muted: "#636681",
|
||||
color_accent: "#d97706",
|
||||
color_success: "#16a34a",
|
||||
color_warning: "#eab308",
|
||||
color_error: "#ef4444",
|
||||
color_info: "#0ea5e9",
|
||||
button_primary_color: "#4f46e5",
|
||||
button_text_color: "#ffffff",
|
||||
border_color: "#818cf8",
|
||||
},
|
||||
Cyberpunk: {
|
||||
color_primary: "#f0db4f",
|
||||
color_background: "#0d0221",
|
||||
color_surface: "#190933",
|
||||
color_dropdown: "#241046",
|
||||
color_navbar: "#190933",
|
||||
color_navbar_text: "#f0db4f",
|
||||
color_text: "#f5e9ff",
|
||||
color_text_muted: "#b08fd6",
|
||||
color_accent: "#ff2a6d",
|
||||
color_success: "#22c55e",
|
||||
color_warning: "#facc15",
|
||||
color_error: "#f87171",
|
||||
color_info: "#38bdf8",
|
||||
button_primary_color: "#ff2a6d",
|
||||
button_text_color: "#ffffff",
|
||||
border_color: "#05d9e8",
|
||||
},
|
||||
Neon: {
|
||||
color_primary: "#39ff14",
|
||||
color_background: "#0a0a0a",
|
||||
color_surface: "#141414",
|
||||
color_dropdown: "#1d1d1d",
|
||||
color_navbar: "#141414",
|
||||
color_navbar_text: "#39ff14",
|
||||
color_text: "#e8ffe8",
|
||||
color_text_muted: "#7fae7f",
|
||||
color_accent: "#ff00ff",
|
||||
color_success: "#22c55e",
|
||||
color_warning: "#facc15",
|
||||
color_error: "#f87171",
|
||||
color_info: "#38bdf8",
|
||||
button_primary_color: "#39ff14",
|
||||
button_text_color: "#0a0a0a",
|
||||
border_color: "#39ff14",
|
||||
},
|
||||
Coffee: {
|
||||
color_primary: "#a16207",
|
||||
color_background: "#f5efe6",
|
||||
color_surface: "#fffaf2",
|
||||
color_dropdown: "#fffaf2",
|
||||
color_navbar: "#fffaf2",
|
||||
color_navbar_text: "#3f2d1c",
|
||||
color_text: "#3f2d1c",
|
||||
color_text_muted: "#8a7560",
|
||||
color_accent: "#15803d",
|
||||
color_success: "#16a34a",
|
||||
color_warning: "#eab308",
|
||||
color_error: "#ef4444",
|
||||
color_info: "#0ea5e9",
|
||||
button_primary_color: "#a16207",
|
||||
button_text_color: "#ffffff",
|
||||
border_color: "#ca8a04",
|
||||
},
|
||||
Arctic: {
|
||||
color_primary: "#0891b2",
|
||||
color_background: "#eef6fb",
|
||||
color_surface: "#ffffff",
|
||||
color_dropdown: "#ffffff",
|
||||
color_navbar: "#ffffff",
|
||||
color_navbar_text: "#0e3a4f",
|
||||
color_text: "#0e3a4f",
|
||||
color_text_muted: "#5b7585",
|
||||
color_accent: "#6366f1",
|
||||
color_success: "#16a34a",
|
||||
color_warning: "#eab308",
|
||||
color_error: "#ef4444",
|
||||
color_info: "#0ea5e9",
|
||||
button_primary_color: "#0891b2",
|
||||
button_text_color: "#ffffff",
|
||||
border_color: "#67e8f9",
|
||||
},
|
||||
Christmas: {
|
||||
color_primary: "#dc2626",
|
||||
color_background: "#f4faf4",
|
||||
color_surface: "#ffffff",
|
||||
color_dropdown: "#ffffff",
|
||||
color_navbar: "#0f3d24",
|
||||
color_navbar_text: "#ffffff",
|
||||
color_text: "#14321f",
|
||||
color_text_muted: "#5f7a68",
|
||||
color_accent: "#15803d",
|
||||
color_success: "#22c55e",
|
||||
color_warning: "#eab308",
|
||||
color_error: "#ef4444",
|
||||
color_info: "#0ea5e9",
|
||||
button_primary_color: "#dc2626",
|
||||
button_text_color: "#ffffff",
|
||||
border_color: "#16a34a",
|
||||
},
|
||||
Dusk: {
|
||||
color_primary: "#e8a33d",
|
||||
color_background: "#1b2230",
|
||||
color_surface: "#232c3d",
|
||||
color_dropdown: "#2b3548",
|
||||
color_navbar: "#232c3d",
|
||||
color_navbar_text: "#dfe5ef",
|
||||
color_text: "#dfe5ef",
|
||||
color_text_muted: "#94a0b5",
|
||||
color_accent: "#5eb0c9",
|
||||
color_success: "#22c55e",
|
||||
color_warning: "#facc15",
|
||||
color_error: "#f87171",
|
||||
color_info: "#38bdf8",
|
||||
button_primary_color: "#e8a33d",
|
||||
button_text_color: "#1b2230",
|
||||
border_color: "#e8a33d",
|
||||
},
|
||||
};
|
||||
|
||||
const LIGHT_BASE: ThemePalette = {
|
||||
color_primary: "#f59e0b",
|
||||
color_background: "#f8fafc",
|
||||
color_surface: "#ffffff",
|
||||
color_dropdown: "#ffffff",
|
||||
color_navbar: "#ffffff",
|
||||
color_navbar_text: "#1e293b",
|
||||
color_text: "#0f172a",
|
||||
color_text_muted: "#64748b",
|
||||
color_accent: "#10b981",
|
||||
color_success: "#16a34a",
|
||||
color_warning: "#eab308",
|
||||
color_error: "#ef4444",
|
||||
color_info: "#0ea5e9",
|
||||
button_primary_color: "#f59e0b",
|
||||
button_text_color: "#1e293b",
|
||||
button_secondary_color: "#22c55e",
|
||||
button_secondary_text_color: "#ffffff",
|
||||
button_danger_color: "#ef4444",
|
||||
button_danger_text_color: "#ffffff",
|
||||
button_outline_color: "#eeb425",
|
||||
button_outline_text_color: "#1a1a2e",
|
||||
link_color: "#b77900",
|
||||
link_hover_color: "#8a5b00",
|
||||
border_color: "#eeb425",
|
||||
gradient_from: "#f59e0b",
|
||||
gradient_to: "#10b981",
|
||||
color_primary: "#f59e0b",
|
||||
color_background: "#f8fafc",
|
||||
color_surface: "#ffffff",
|
||||
color_dropdown: "#ffffff",
|
||||
color_navbar: "#ffffff",
|
||||
color_navbar_text: "#1e293b",
|
||||
color_text: "#0f172a",
|
||||
color_text_muted: "#64748b",
|
||||
color_accent: "#10b981",
|
||||
color_success: "#16a34a",
|
||||
color_warning: "#eab308",
|
||||
color_error: "#ef4444",
|
||||
color_info: "#0ea5e9",
|
||||
button_primary_color: "#f59e0b",
|
||||
button_text_color: "#1e293b",
|
||||
button_secondary_color: "#22c55e",
|
||||
button_secondary_text_color: "#ffffff",
|
||||
button_danger_color: "#ef4444",
|
||||
button_danger_text_color: "#ffffff",
|
||||
button_outline_color: "#eeb425",
|
||||
button_outline_text_color: "#1a1a2e",
|
||||
link_color: "#b77900",
|
||||
link_hover_color: "#8a5b00",
|
||||
border_color: "#eeb425",
|
||||
gradient_from: "#f59e0b",
|
||||
gradient_to: "#10b981",
|
||||
};
|
||||
|
||||
const DARK_BASE: ThemePalette = {
|
||||
...LIGHT_BASE,
|
||||
color_background: "#0b0d14",
|
||||
color_surface: "#141820",
|
||||
color_dropdown: "#1d222b",
|
||||
color_navbar: "#141820",
|
||||
color_navbar_text: "#e5e7eb",
|
||||
color_text: "#e5e7eb",
|
||||
color_text_muted: "#94a3b8",
|
||||
button_text_color: "#0b0d14",
|
||||
button_secondary_text_color: "#08130b",
|
||||
button_danger_text_color: "#160606",
|
||||
button_outline_text_color: "#f8fafc",
|
||||
link_color: "#f6c453",
|
||||
link_hover_color: "#ffe08a",
|
||||
...LIGHT_BASE,
|
||||
color_background: "#0b0d14",
|
||||
color_surface: "#141820",
|
||||
color_dropdown: "#1d222b",
|
||||
color_navbar: "#141820",
|
||||
color_navbar_text: "#e5e7eb",
|
||||
color_text: "#e5e7eb",
|
||||
color_text_muted: "#94a3b8",
|
||||
button_text_color: "#0b0d14",
|
||||
button_secondary_text_color: "#08130b",
|
||||
button_danger_text_color: "#160606",
|
||||
button_outline_text_color: "#f8fafc",
|
||||
link_color: "#f6c453",
|
||||
link_hover_color: "#ffe08a",
|
||||
};
|
||||
|
||||
const DARK_FIRST = new Set(["Midnight", "Galaxy", "Cyberpunk", "Neon", "Dusk"]);
|
||||
|
||||
function brandValues(source: Partial<ThemePalette>): Partial<ThemePalette> {
|
||||
return {
|
||||
color_primary: source.color_primary,
|
||||
color_accent: source.color_accent,
|
||||
color_success: source.color_success,
|
||||
color_warning: source.color_warning,
|
||||
color_error: source.color_error,
|
||||
color_info: source.color_info,
|
||||
button_primary_color: source.button_primary_color ?? source.color_primary,
|
||||
border_color: source.border_color ?? source.color_primary,
|
||||
gradient_from: source.color_primary,
|
||||
gradient_to: source.color_accent,
|
||||
button_outline_color: source.border_color ?? source.color_primary,
|
||||
};
|
||||
return {
|
||||
color_primary: source.color_primary,
|
||||
color_accent: source.color_accent,
|
||||
color_success: source.color_success,
|
||||
color_warning: source.color_warning,
|
||||
color_error: source.color_error,
|
||||
color_info: source.color_info,
|
||||
button_primary_color: source.button_primary_color ?? source.color_primary,
|
||||
border_color: source.border_color ?? source.color_primary,
|
||||
gradient_from: source.color_primary,
|
||||
gradient_to: source.color_accent,
|
||||
button_outline_color: source.border_color ?? source.color_primary,
|
||||
};
|
||||
}
|
||||
|
||||
function completePalette(base: ThemePalette, values: Partial<ThemePalette>): ThemePalette {
|
||||
const merged = { ...base, ...values };
|
||||
merged.button_secondary_color = values.button_secondary_color ?? merged.color_accent;
|
||||
merged.button_outline_color = values.button_outline_color ?? merged.border_color;
|
||||
merged.gradient_from = values.gradient_from ?? merged.color_primary;
|
||||
merged.gradient_to = values.gradient_to ?? merged.color_accent;
|
||||
return merged;
|
||||
function completePalette(
|
||||
base: ThemePalette,
|
||||
values: Partial<ThemePalette>,
|
||||
): ThemePalette {
|
||||
const merged = { ...base, ...values };
|
||||
merged.button_secondary_color =
|
||||
values.button_secondary_color ?? merged.color_accent;
|
||||
merged.button_outline_color =
|
||||
values.button_outline_color ?? merged.border_color;
|
||||
merged.gradient_from = values.gradient_from ?? merged.color_primary;
|
||||
merged.gradient_to = values.gradient_to ?? merged.color_accent;
|
||||
return merged;
|
||||
}
|
||||
|
||||
export const PRESETS: Record<string, ThemePreset> = Object.fromEntries(
|
||||
Object.entries(LEGACY_PALETTES).map(([name, palette]) => {
|
||||
const light = DARK_FIRST.has(name)
|
||||
? completePalette(LIGHT_BASE, brandValues(palette))
|
||||
: completePalette(LIGHT_BASE, palette);
|
||||
const dark = DARK_FIRST.has(name)
|
||||
? completePalette(DARK_BASE, palette)
|
||||
: completePalette(DARK_BASE, brandValues(palette));
|
||||
return [name, { light, dark } satisfies ThemePreset];
|
||||
}),
|
||||
Object.entries(LEGACY_PALETTES).map(([name, palette]) => {
|
||||
const light = DARK_FIRST.has(name)
|
||||
? completePalette(LIGHT_BASE, brandValues(palette))
|
||||
: completePalette(LIGHT_BASE, palette);
|
||||
const dark = DARK_FIRST.has(name)
|
||||
? completePalette(DARK_BASE, palette)
|
||||
: completePalette(DARK_BASE, brandValues(palette));
|
||||
return [name, { light, dark } satisfies ThemePreset];
|
||||
}),
|
||||
);
|
||||
Reference in new issue
Block a user