const STORAGE_KEY = 'mobux:theme';
const DEFAULT_THEME = 'tomorrow-night-soft';
export const THEMES = [
{
id: 'tomorrow-night-soft',
label: 'Tomorrow Night Soft',
aceTheme: 'ace/theme/tomorrow_night',
palette: [
'#1e1e1e', '#cc6666', '#b5bd68', '#f0c674',
'#81a2be', '#b294bb', '#8abeb7', '#c5c8c6',
'#5c6370', '#e06c75', '#98c379', '#e5c07b',
'#61afef', '#c678dd', '#56b6c2', '#ffffff',
],
},
{
id: 'gruvbox-dark-soft',
label: 'Gruvbox Dark Soft',
aceTheme: 'ace/theme/gruvbox',
palette: [
'#32302f', '#cc241d', '#98971a', '#d79921',
'#458588', '#b16286', '#689d6a', '#a89984',
'#928374', '#fb4934', '#b8bb26', '#fabd2f',
'#83a598', '#d3869b', '#8ec07c', '#ebdbb2',
],
},
{
id: 'nord',
label: 'Nord',
aceTheme: 'ace/theme/nord_dark',
palette: [
'#2e3440', '#bf616a', '#a3be8c', '#ebcb8b',
'#81a1c1', '#b48ead', '#88c0d0', '#e5e9f0',
'#4c566a', '#bf616a', '#a3be8c', '#ebcb8b',
'#81a1c1', '#b48ead', '#8fbcbb', '#eceff4',
],
},
{
id: 'solarized-dark',
label: 'Solarized Dark',
aceTheme: 'ace/theme/solarized_dark',
palette: [
'#073642', '#dc322f', '#859900', '#b58900',
'#268bd2', '#d33682', '#2aa198', '#eee8d5',
'#002b36', '#cb4b16', '#586e75', '#657b83',
'#839496', '#6c71c4', '#93a1a1', '#fdf6e3',
],
},
{
id: 'solarized-light',
label: 'Solarized Light',
aceTheme: 'ace/theme/solarized_light',
background: '#fdf6e3',
foreground: '#657b83',
palette: [
'#073642', '#dc322f', '#859900', '#b58900',
'#268bd2', '#d33682', '#2aa198', '#eee8d5',
'#002b36', '#cb4b16', '#586e75', '#657b83',
'#839496', '#6c71c4', '#93a1a1', '#fdf6e3',
],
},
{
id: 'gruvbox-light',
label: 'Gruvbox Light',
aceTheme: 'ace/theme/gruvbox_light_hard',
background: '#f9f5d7',
foreground: '#3c3836',
palette: [
'#3c3836', '#cc241d', '#98971a', '#d79921',
'#458588', '#b16286', '#689d6a', '#7c6f64',
'#928374', '#9d0006', '#79740e', '#b57614',
'#076678', '#8f3f71', '#427b58', '#282828',
],
},
{
id: 'github-light',
label: 'GitHub Light',
aceTheme: 'ace/theme/github_light_default',
background: '#f6f8fa',
foreground: '#24292e',
palette: [
'#24292e', '#d73a49', '#28a745', '#dbab09',
'#0366d6', '#5a32a3', '#1b7c83', '#6a737d',
'#959da5', '#cb2431', '#22863a', '#b08800',
'#005cc5', '#5a32a3', '#3192aa', '#d1d5da',
],
},
];
const BY_ID = Object.fromEntries(THEMES.map((t) => [t.id, t]));
export function getStoredThemeId() {
try {
const v = localStorage.getItem(STORAGE_KEY);
if (v && BY_ID[v]) return v;
} catch (_) {}
return DEFAULT_THEME;
}
export function setStoredThemeId(id) {
if (!BY_ID[id]) return;
try { localStorage.setItem(STORAGE_KEY, id); } catch (_) {}
}
export function getTheme(id) {
return BY_ID[id] || BY_ID[DEFAULT_THEME];
}
export function applyReaderVars(theme) {
const reader = document.getElementById('reader');
if (!reader) return;
for (let i = 0; i < 16; i++) {
reader.style.setProperty(`--ansi-${i}`, theme.palette[i]);
}
reader.style.background = theme.background || theme.palette[0];
reader.style.color = theme.foreground || theme.palette[7] || '#c5c8c6';
}
export function applyTerminalColors(theme) {
const sterk = window.__sterk;
if (sterk && sterk.options && sterk.options.theme && Array.isArray(sterk.options.theme.palette)) {
sterk.options.theme.palette = theme.palette.slice(0, 16);
sterk.options.theme.background = theme.background || theme.palette[0];
sterk.options.theme.foreground = theme.foreground || theme.palette[7] || '#c5c8c6';
return true;
}
const xterm = window.__xterm;
if (xterm && xterm.options) {
const p = theme.palette;
xterm.options.theme = {
background: theme.background || p[0],
foreground: theme.foreground || p[7] || '#c5c8c6',
black: p[0], red: p[1], green: p[2], yellow: p[3],
blue: p[4], magenta: p[5], cyan: p[6], white: p[7],
brightBlack: p[8], brightRed: p[9], brightGreen: p[10], brightYellow: p[11],
brightBlue: p[12], brightMagenta: p[13], brightCyan: p[14], brightWhite: p[15],
};
return true;
}
return false;
}
export function applyEditorTheme(theme, editor) {
if (!editor || typeof editor.setTheme !== 'function') return false;
editor.setTheme(theme.aceTheme);
return true;
}
export function applyTheme(id, { editor } = {}) {
const theme = getTheme(id);
applyReaderVars(theme);
applyTerminalColors(theme);
if (editor) applyEditorTheme(theme, editor);
return theme;
}