Files
ObsiGate/frontend/js/themes.js
T
bruno 943005328c
CI / lint (push) Successful in 2m5s
CI / security (push) Successful in 1m27s
CI / test (push) Successful in 4m10s
CI / build (push) Successful in 1m23s
CI / e2e (push) Successful in 13m55s
feat: barre d'outils de lecture epinglee, coloration syntaxique des fichiers de code et avatars predefinis (#115, #117, BUG-078)
2026-09-24 16:21:45 -04:00

754 lines
43 KiB
JavaScript

/* ObsiGate — Theme System
* 15 themes x 2 modes (dark/light)
* Persisted in localStorage as 'obsigate-theme'
* Usage: import { initThemes, applyTheme, getCurrentTheme, THEMES } from './themes.js'
*/
// ── Theme definitions ────────────────────────────────────────────────
// Each theme has 'dark' and 'light' variants.
// CSS variables are applied to :root via setProperty.
var THEMES = {
'defaut-obsigate': {
name: 'Defaut ObsiGate',
desc: 'Theme original',
modes: {
dark: {
'--bg-primary': '#0f1117', '--bg-secondary': '#161b22', '--bg-sidebar': '#13161d',
'--bg-hover': '#1f2430', '--border': '#21262d', '--text-primary': '#e6edf3',
'--text-secondary': '#8b949e', '--text-muted': '#484f58', '--accent': '#58a6ff',
'--accent-green': '#3fb950', '--tag-bg': '#1f2a3a', '--tag-text': '#79c0ff',
'--code-bg': '#161b22', '--search-bg': '#21262d', '--scrollbar': '#30363d',
'--resize-handle': '#30363d', '--overlay-bg': 'rgba(0,0,0,0.5)',
'--danger': '#ff7b72', '--danger-bg': '#3d1a18', '--success': '#3fb950', '--success-bg': '#1a3d1f',
'--accent-card': '#58a6ff', '--accent-bg': '#1f2a3a', '--accent-text': '#79c0ff',
'--green': '#3fb950', '--green-bg': '#1a3d1f', '--purple': '#a371f7', '--purple-bg': '#2d1b4e',
'--surface': '#161b22', '--surface2': '#0f1117', '--surface3': '#0d0f14',
'--border-md': '#30363d', '--text': '#e6edf3', '--text-2': '#8b949e', '--text-3': '#484f58',
'--ok': '#34d399', '--warn': '#fbbf24', '--ai': '#8b5cf6', '--err': '#f87171'
},
light: {
'--bg-primary': '#ffffff', '--bg-secondary': '#f6f8fa', '--bg-sidebar': '#f0f2f5',
'--bg-hover': '#e8ecf0', '--border': '#d0d7de', '--text-primary': '#1f2328',
'--text-secondary': '#57606a', '--text-muted': '#9198a1', '--accent': '#0969da',
'--accent-green': '#1a7f37', '--tag-bg': '#ddf4ff', '--tag-text': '#0969da',
'--code-bg': '#f6f8fa', '--search-bg': '#ffffff', '--scrollbar': '#d0d7de',
'--resize-handle': '#d0d7de', '--overlay-bg': 'rgba(0,0,0,0.3)',
'--danger': '#cf222e', '--danger-bg': '#ffebe9', '--success': '#1a7f37', '--success-bg': '#dafbe1',
'--accent-card': '#0969da', '--accent-bg': '#ddf4ff', '--accent-text': '#0969da',
'--green': '#1a7f37', '--green-bg': '#dafbe1', '--purple': '#8250df', '--purple-bg': '#fbefff',
'--surface': '#f6f8fa', '--surface2': '#ffffff', '--surface3': '#f0f2f5',
'--border-md': '#d0d7de', '--text': '#1f2328', '--text-2': '#57606a', '--text-3': '#9198a1',
'--ok': '#1a7f37', '--warn': '#9a6700', '--ai': '#8250df', '--err': '#cf222e'
}
}
},
'github': {
name: 'GitHub', desc: 'Contraste doux',
modes: {
dark: {
'--bg-primary': '#0d1117', '--bg-secondary': '#161b22', '--bg-sidebar': '#0d1117',
'--bg-hover': '#1c2128', '--border': '#30363d', '--text-primary': '#f0f6fc',
'--text-secondary': '#8b949e', '--text-muted': '#6e7681', '--accent': '#58a6ff',
'--accent-green': '#3fb950', '--tag-bg': '#13233a', '--tag-text': '#58a6ff',
'--code-bg': '#161b22', '--search-bg': '#0d1117', '--scrollbar': '#30363d',
'--resize-handle': '#30363d', '--overlay-bg': 'rgba(0,0,0,0.6)',
'--danger': '#f85149', '--danger-bg': '#490202', '--success': '#3fb950', '--success-bg': '#04260f',
'--accent-card': '#58a6ff', '--accent-bg': '#13233a', '--accent-text': '#58a6ff',
'--green': '#3fb950', '--green-bg': '#04260f', '--purple': '#a371f7', '--purple-bg': '#1c1130',
'--surface': '#161b22', '--surface2': '#0d1117', '--surface3': '#010409',
'--border-md': '#30363d', '--text': '#f0f6fc', '--text-2': '#8b949e', '--text-3': '#6e7681',
'--ok': '#3fb950', '--warn': '#d29922', '--ai': '#a371f7', '--err': '#f85149'
},
light: {
'--bg-primary': '#ffffff', '--bg-secondary': '#f6f8fa', '--bg-sidebar': '#f6f8fa',
'--bg-hover': '#eaeef2', '--border': '#d0d7de', '--text-primary': '#1f2328',
'--text-secondary': '#656d76', '--text-muted': '#8c959f', '--accent': '#0969da',
'--accent-green': '#1a7f37', '--tag-bg': '#ddf4ff', '--tag-text': '#0969da',
'--code-bg': '#f6f8fa', '--search-bg': '#ffffff', '--scrollbar': '#d0d7de',
'--resize-handle': '#d0d7de', '--overlay-bg': 'rgba(0,0,0,0.25)',
'--danger': '#cf222e', '--danger-bg': '#ffebe9', '--success': '#1a7f37', '--success-bg': '#dafbe1',
'--accent-card': '#0969da', '--accent-bg': '#ddf4ff', '--accent-text': '#0969da',
'--green': '#1a7f37', '--green-bg': '#dafbe1', '--purple': '#8250df', '--purple-bg': '#fbefff',
'--surface': '#f6f8fa', '--surface2': '#ffffff', '--surface3': '#ebedf0',
'--border-md': '#d0d7de', '--text': '#1f2328', '--text-2': '#656d76', '--text-3': '#8c959f',
'--ok': '#1a7f37', '--warn': '#9a6700', '--ai': '#8250df', '--err': '#cf222e'
}
}
},
'linear': {
name: 'Linear', desc: 'Dégradés subtils',
modes: {
dark: {
'--bg-primary': '#1a1a2e', '--bg-secondary': '#16162a', '--bg-sidebar': '#12121f',
'--bg-hover': '#222240', '--border': '#2a2a45', '--text-primary': '#e1e1f5',
'--text-secondary': '#8888aa', '--text-muted': '#555577', '--accent': '#5e6ad2',
'--accent-green': '#2ecc71', '--tag-bg': '#222050', '--tag-text': '#8b95e0',
'--code-bg': '#16162a', '--search-bg': '#1e1e38', '--scrollbar': '#2a2a45',
'--resize-handle': '#2a2a45', '--overlay-bg': 'rgba(0,0,0,0.6)',
'--danger': '#e0556a', '--danger-bg': '#361520', '--success': '#2ecc71', '--success-bg': '#0d2818',
'--accent-card': '#5e6ad2', '--accent-bg': '#222050', '--accent-text': '#8b95e0',
'--green': '#2ecc71', '--green-bg': '#0d2818', '--purple': '#9b6bff', '--purple-bg': '#25183d',
'--surface': '#16162a', '--surface2': '#1a1a2e', '--surface3': '#12121f',
'--border-md': '#2a2a45', '--text': '#e1e1f5', '--text-2': '#8888aa', '--text-3': '#555577',
'--ok': '#2ecc71', '--warn': '#f0b429', '--ai': '#9b6bff', '--err': '#e0556a'
},
light: {
'--bg-primary': '#fafafa', '--bg-secondary': '#f0f0f5', '--bg-sidebar': '#e8e8f0',
'--bg-hover': '#e0e0ea', '--border': '#d5d5e0', '--text-primary': '#1a1a2e',
'--text-secondary': '#5c5c7a', '--text-muted': '#9090a8', '--accent': '#5e6ad2',
'--accent-green': '#1a8b4a', '--tag-bg': '#e8e8ff', '--tag-text': '#5e6ad2',
'--code-bg': '#f0f0f5', '--search-bg': '#fafafa', '--scrollbar': '#d5d5e0',
'--resize-handle': '#d5d5e0', '--overlay-bg': 'rgba(0,0,0,0.2)',
'--danger': '#c92a3e', '--danger-bg': '#ffeaea', '--success': '#1a8b4a', '--success-bg': '#e0ffe0',
'--accent-card': '#5e6ad2', '--accent-bg': '#e8e8ff', '--accent-text': '#5e6ad2',
'--green': '#1a8b4a', '--green-bg': '#e0ffe0', '--purple': '#7c5ce0', '--purple-bg': '#efe8ff',
'--surface': '#f0f0f5', '--surface2': '#fafafa', '--surface3': '#e8e8f0',
'--border-md': '#d5d5e0', '--text': '#1a1a2e', '--text-2': '#5c5c7a', '--text-3': '#9090a8',
'--ok': '#1a8b4a', '--warn': '#9a6700', '--ai': '#7c5ce0', '--err': '#c92a3e'
}
}
},
'spotify': {
name: 'Spotify', desc: 'Noir pur & vert',
modes: {
dark: {
'--bg-primary': '#000000', '--bg-secondary': '#121212', '--bg-sidebar': '#000000',
'--bg-hover': '#1a1a1a', '--border': '#282828', '--text-primary': '#ffffff',
'--text-secondary': '#b3b3b3', '--text-muted': '#727272', '--accent': '#1db954',
'--accent-green': '#1db954', '--tag-bg': '#0d3317', '--tag-text': '#1db954',
'--code-bg': '#121212', '--search-bg': '#242424', '--scrollbar': '#333333',
'--resize-handle': '#282828', '--overlay-bg': 'rgba(0,0,0,0.7)',
'--danger': '#e22134', '--danger-bg': '#2a0a0e', '--success': '#1db954', '--success-bg': '#0d3317',
'--accent-card': '#1db954', '--accent-bg': '#0d3317', '--accent-text': '#1db954',
'--green': '#1db954', '--green-bg': '#0d3317', '--purple': '#af2896', '--purple-bg': '#2a0d33',
'--surface': '#121212', '--surface2': '#000000', '--surface3': '#000000',
'--border-md': '#282828', '--text': '#ffffff', '--text-2': '#b3b3b3', '--text-3': '#727272',
'--ok': '#1db954', '--warn': '#f59b23', '--ai': '#af2896', '--err': '#e22134'
},
light: {
'--bg-primary': '#ffffff', '--bg-secondary': '#f5f5f5', '--bg-sidebar': '#f0f0f0',
'--bg-hover': '#e5e5e5', '--border': '#d5d5d5', '--text-primary': '#121212',
'--text-secondary': '#575757', '--text-muted': '#8c8c8c', '--accent': '#1db954',
'--accent-green': '#1db954', '--tag-bg': '#e0ffe0', '--tag-text': '#128a3c',
'--code-bg': '#f5f5f5', '--search-bg': '#ffffff', '--scrollbar': '#d5d5d5',
'--resize-handle': '#d5d5d5', '--overlay-bg': 'rgba(0,0,0,0.2)',
'--danger': '#c92a2a', '--danger-bg': '#ffe3e3', '--success': '#1db954', '--success-bg': '#e0ffe0',
'--accent-card': '#1db954', '--accent-bg': '#e0ffe0', '--accent-text': '#128a3c',
'--green': '#1db954', '--green-bg': '#e0ffe0', '--purple': '#8a2be2', '--purple-bg': '#f3e0ff',
'--surface': '#f5f5f5', '--surface2': '#ffffff', '--surface3': '#f0f0f0',
'--border-md': '#d5d5d5', '--text': '#121212', '--text-2': '#575757', '--text-3': '#8c8c8c',
'--ok': '#1db954', '--warn': '#9a6700', '--ai': '#8a2be2', '--err': '#c92a2a'
}
}
},
'notion': {
name: 'Notion', desc: 'Lecture propre',
modes: {
dark: {
'--bg-primary': '#191919', '--bg-secondary': '#202020', '--bg-sidebar': '#191919',
'--bg-hover': '#262626', '--border': '#333333', '--text-primary': '#e6e6e6',
'--text-secondary': '#999999', '--text-muted': '#666666', '--accent': '#4b85e8',
'--accent-green': '#0ca16a', '--tag-bg': '#1c2744', '--tag-text': '#6ba1f0',
'--code-bg': '#202020', '--search-bg': '#262626', '--scrollbar': '#333333',
'--resize-handle': '#333333', '--overlay-bg': 'rgba(0,0,0,0.6)',
'--danger': '#e03e3e', '--danger-bg': '#2a1010', '--success': '#0ca16a', '--success-bg': '#0d2818',
'--accent-card': '#4b85e8', '--accent-bg': '#1c2744', '--accent-text': '#6ba1f0',
'--green': '#0ca16a', '--green-bg': '#0d2818', '--purple': '#9065e0', '--purple-bg': '#24183d',
'--surface': '#202020', '--surface2': '#191919', '--surface3': '#141414',
'--border-md': '#333333', '--text': '#e6e6e6', '--text-2': '#999999', '--text-3': '#666666',
'--ok': '#0ca16a', '--warn': '#dfab3e', '--ai': '#9065e0', '--err': '#e03e3e'
},
light: {
'--bg-primary': '#ffffff', '--bg-secondary': '#f7f6f3', '--bg-sidebar': '#f7f6f3',
'--bg-hover': '#edece9', '--border': '#e3e2e0', '--text-primary': '#37352f',
'--text-secondary': '#787774', '--text-muted': '#abaaa7', '--accent': '#4b85e8',
'--accent-green': '#0ca16a', '--tag-bg': '#e8f0fe', '--tag-text': '#4b85e8',
'--code-bg': '#f7f6f3', '--search-bg': '#ffffff', '--scrollbar': '#e3e2e0',
'--resize-handle': '#e3e2e0', '--overlay-bg': 'rgba(0,0,0,0.15)',
'--danger': '#e03e3e', '--danger-bg': '#fdebec', '--success': '#0ca16a', '--success-bg': '#e6f7ec',
'--accent-card': '#4b85e8', '--accent-bg': '#e8f0fe', '--accent-text': '#4b85e8',
'--green': '#0ca16a', '--green-bg': '#e6f7ec', '--purple': '#9065e0', '--purple-bg': '#f3effc',
'--surface': '#f7f6f3', '--surface2': '#ffffff', '--surface3': '#edece9',
'--border-md': '#e3e2e0', '--text': '#37352f', '--text-2': '#787774', '--text-3': '#abaaa7',
'--ok': '#0ca16a', '--warn': '#dfab3e', '--ai': '#9065e0', '--err': '#e03e3e'
}
}
},
'discord': {
name: 'Discord', desc: 'Standard communautaire',
modes: {
dark: {
'--bg-primary': '#313338', '--bg-secondary': '#2b2d31', '--bg-sidebar': '#1e1f22',
'--bg-hover': '#3c3e45', '--border': '#3f4147', '--text-primary': '#f2f3f5',
'--text-secondary': '#b5bac1', '--text-muted': '#80848e', '--accent': '#5865f2',
'--accent-green': '#23a559', '--tag-bg': '#28315c', '--tag-text': '#8891f2',
'--code-bg': '#2b2d31', '--search-bg': '#383a40', '--scrollbar': '#1a1b1e',
'--resize-handle': '#3f4147', '--overlay-bg': 'rgba(0,0,0,0.7)',
'--danger': '#da373c', '--danger-bg': '#3a1518', '--success': '#23a559', '--success-bg': '#122b1a',
'--accent-card': '#5865f2', '--accent-bg': '#28315c', '--accent-text': '#8891f2',
'--green': '#23a559', '--green-bg': '#122b1a', '--purple': '#9c5bf0', '--purple-bg': '#2c1a46',
'--surface': '#2b2d31', '--surface2': '#313338', '--surface3': '#1e1f22',
'--border-md': '#3f4147', '--text': '#f2f3f5', '--text-2': '#b5bac1', '--text-3': '#80848e',
'--ok': '#23a559', '--warn': '#f0b232', '--ai': '#9c5bf0', '--err': '#da373c'
},
light: {
'--bg-primary': '#ffffff', '--bg-secondary': '#f2f3f5', '--bg-sidebar': '#e3e5e8',
'--bg-hover': '#e3e5e8', '--border': '#d4d7dc', '--text-primary': '#313338',
'--text-secondary': '#5c5e66', '--text-muted': '#91949e', '--accent': '#5865f2',
'--accent-green': '#248046', '--tag-bg': '#e8eafe', '--tag-text': '#4752c4',
'--code-bg': '#f2f3f5', '--search-bg': '#ffffff', '--scrollbar': '#d4d7dc',
'--resize-handle': '#d4d7dc', '--overlay-bg': 'rgba(0,0,0,0.2)',
'--danger': '#d92028', '--danger-bg': '#fde8e8', '--success': '#248046', '--success-bg': '#e6f7e8',
'--accent-card': '#5865f2', '--accent-bg': '#e8eafe', '--accent-text': '#4752c4',
'--green': '#248046', '--green-bg': '#e6f7e8', '--purple': '#8b5cf6', '--purple-bg': '#f0ebff',
'--surface': '#f2f3f5', '--surface2': '#ffffff', '--surface3': '#e3e5e8',
'--border-md': '#d4d7dc', '--text': '#313338', '--text-2': '#5c5e66', '--text-3': '#91949e',
'--ok': '#248046', '--warn': '#9a6700', '--ai': '#8b5cf6', '--err': '#d92028'
}
}
},
'dracula': {
name: 'Dracula', desc: 'Accents rose & violet',
modes: {
dark: {
'--bg-primary': '#282a36', '--bg-secondary': '#21222c', '--bg-sidebar': '#1d1e26',
'--bg-hover': '#343746', '--border': '#3b3d54', '--text-primary': '#f8f8f2',
'--text-secondary': '#b2b2b2', '--text-muted': '#6272a4', '--accent': '#bd93f9',
'--accent-green': '#50fa7b', '--tag-bg': '#2a2240', '--tag-text': '#bd93f9',
'--code-bg': '#21222c', '--search-bg': '#343746', '--scrollbar': '#44475a',
'--resize-handle': '#3b3d54', '--overlay-bg': 'rgba(0,0,0,0.6)',
'--danger': '#ff5555', '--danger-bg': '#3a1a1a', '--success': '#50fa7b', '--success-bg': '#0d2818',
'--accent-card': '#bd93f9', '--accent-bg': '#2a2240', '--accent-text': '#bd93f9',
'--green': '#50fa7b', '--green-bg': '#0d2818', '--purple': '#bd93f9', '--purple-bg': '#2a2240',
'--surface': '#21222c', '--surface2': '#282a36', '--surface3': '#1d1e26',
'--border-md': '#3b3d54', '--text': '#f8f8f2', '--text-2': '#b2b2b2', '--text-3': '#6272a4',
'--ok': '#50fa7b', '--warn': '#f1fa8c', '--ai': '#bd93f9', '--err': '#ff5555'
},
light: {
'--bg-primary': '#f8f8f2', '--bg-secondary': '#f0f0ea', '--bg-sidebar': '#e8e8e0',
'--bg-hover': '#e0e0d8', '--border': '#d5d5cc', '--text-primary': '#282a36',
'--text-secondary': '#4d5066', '--text-muted': '#8b8fa8', '--accent': '#8a5cf6',
'--accent-green': '#3d8f54', '--tag-bg': '#ede0ff', '--tag-text': '#8a5cf6',
'--code-bg': '#f0f0ea', '--search-bg': '#f8f8f2', '--scrollbar': '#d5d5cc',
'--resize-handle': '#d5d5cc', '--overlay-bg': 'rgba(0,0,0,0.15)',
'--danger': '#d7373f', '--danger-bg': '#fde8e8', '--success': '#3d8f54', '--success-bg': '#e6f7e8',
'--accent-card': '#8a5cf6', '--accent-bg': '#ede0ff', '--accent-text': '#8a5cf6',
'--green': '#3d8f54', '--green-bg': '#e6f7e8', '--purple': '#8a5cf6', '--purple-bg': '#ede0ff',
'--surface': '#f0f0ea', '--surface2': '#f8f8f2', '--surface3': '#e8e8e0',
'--border-md': '#d5d5cc', '--text': '#282a36', '--text-2': '#4d5066', '--text-3': '#8b8fa8',
'--ok': '#3d8f54', '--warn': '#8b7500', '--ai': '#8a5cf6', '--err': '#d7373f'
}
}
},
'one-dark': {
name: 'One Dark', desc: 'Inspire d\'Atom',
modes: {
dark: {
'--bg-primary': '#282c34', '--bg-secondary': '#21252b', '--bg-sidebar': '#1c1f26',
'--bg-hover': '#333842', '--border': '#3e4452', '--text-primary': '#abb2bf',
'--text-secondary': '#828997', '--text-muted': '#5c6370', '--accent': '#61afef',
'--accent-green': '#98c379', '--tag-bg': '#1e3350', '--tag-text': '#61afef',
'--code-bg': '#21252b', '--search-bg': '#333842', '--scrollbar': '#3e4452',
'--resize-handle': '#3e4452', '--overlay-bg': 'rgba(0,0,0,0.6)',
'--danger': '#e06c75', '--danger-bg': '#351b1e', '--success': '#98c379', '--success-bg': '#1a2e1a',
'--accent-card': '#61afef', '--accent-bg': '#1e3350', '--accent-text': '#61afef',
'--green': '#98c379', '--green-bg': '#1a2e1a', '--purple': '#c678dd', '--purple-bg': '#2c1a3a',
'--surface': '#21252b', '--surface2': '#282c34', '--surface3': '#1c1f26',
'--border-md': '#3e4452', '--text': '#abb2bf', '--text-2': '#828997', '--text-3': '#5c6370',
'--ok': '#98c379', '--warn': '#e5c07b', '--ai': '#c678dd', '--err': '#e06c75'
},
light: {
'--bg-primary': '#fafafa', '--bg-secondary': '#f0f0f0', '--bg-sidebar': '#e8e8e8',
'--bg-hover': '#e0e0e0', '--border': '#d4d4d4', '--text-primary': '#383a42',
'--text-secondary': '#696c77', '--text-muted': '#9ca0a4', '--accent': '#4078f2',
'--accent-green': '#50a14f', '--tag-bg': '#e0e8ff', '--tag-text': '#4078f2',
'--code-bg': '#f0f0f0', '--search-bg': '#fafafa', '--scrollbar': '#d4d4d4',
'--resize-handle': '#d4d4d4', '--overlay-bg': 'rgba(0,0,0,0.15)',
'--danger': '#e45649', '--danger-bg': '#fde8e8', '--success': '#50a14f', '--success-bg': '#e6f7e6',
'--accent-card': '#4078f2', '--accent-bg': '#e0e8ff', '--accent-text': '#4078f2',
'--green': '#50a14f', '--green-bg': '#e6f7e6', '--purple': '#a626a4', '--purple-bg': '#f8e0f8',
'--surface': '#f0f0f0', '--surface2': '#fafafa', '--surface3': '#e8e8e8',
'--border-md': '#d4d4d4', '--text': '#383a42', '--text-2': '#696c77', '--text-3': '#9ca0a4',
'--ok': '#50a14f', '--warn': '#986801', '--ai': '#a626a4', '--err': '#e45649'
}
}
},
'tokyo-night': {
name: 'Tokyo Night', desc: 'Bleu neon',
modes: {
dark: {
'--bg-primary': '#1a1b26', '--bg-secondary': '#16161e', '--bg-sidebar': '#13131a',
'--bg-hover': '#24283b', '--border': '#2f3545', '--text-primary': '#c0caf5',
'--text-secondary': '#a9b1d6', '--text-muted': '#565f89', '--accent': '#7aa2f7',
'--accent-green': '#9ece6a', '--tag-bg': '#1f2845', '--tag-text': '#7aa2f7',
'--code-bg': '#16161e', '--search-bg': '#24283b', '--scrollbar': '#2f3545',
'--resize-handle': '#2f3545', '--overlay-bg': 'rgba(0,0,0,0.7)',
'--danger': '#f7768e', '--danger-bg': '#361a22', '--success': '#9ece6a', '--success-bg': '#1a2e1a',
'--accent-card': '#7aa2f7', '--accent-bg': '#1f2845', '--accent-text': '#7aa2f7',
'--green': '#9ece6a', '--green-bg': '#1a2e1a', '--purple': '#bb9af7', '--purple-bg': '#241a3a',
'--surface': '#16161e', '--surface2': '#1a1b26', '--surface3': '#13131a',
'--border-md': '#2f3545', '--text': '#c0caf5', '--text-2': '#a9b1d6', '--text-3': '#565f89',
'--ok': '#9ece6a', '--warn': '#e0af68', '--ai': '#bb9af7', '--err': '#f7768e'
},
light: {
'--bg-primary': '#d5d6db', '--bg-secondary': '#c8c9d0', '--bg-sidebar': '#bfc0c8',
'--bg-hover': '#bbbbc4', '--border': '#a9aab3', '--text-primary': '#343b58',
'--text-secondary': '#565a6e', '--text-muted': '#848cb0', '--accent': '#34548a',
'--accent-green': '#485e30', '--tag-bg': '#dfe5f5', '--tag-text': '#34548a',
'--code-bg': '#c8c9d0', '--search-bg': '#d5d6db', '--scrollbar': '#a9aab3',
'--resize-handle': '#a9aab3', '--overlay-bg': 'rgba(0,0,0,0.15)',
'--danger': '#8c4351', '--danger-bg': '#f8e0e0', '--success': '#485e30', '--success-bg': '#e0f0d8',
'--accent-card': '#34548a', '--accent-bg': '#dfe5f5', '--accent-text': '#34548a',
'--green': '#485e30', '--green-bg': '#e0f0d8', '--purple': '#5a4a9a', '--purple-bg': '#e8e0f8',
'--surface': '#c8c9d0', '--surface2': '#d5d6db', '--surface3': '#bfc0c8',
'--border-md': '#a9aab3', '--text': '#343b58', '--text-2': '#565a6e', '--text-3': '#848cb0',
'--ok': '#485e30', '--warn': '#8f5e15', '--ai': '#5a4a9a', '--err': '#8c4351'
}
}
},
'nord': {
name: 'Nord', desc: 'Style arctique',
modes: {
dark: {
'--bg-primary': '#2e3440', '--bg-secondary': '#3b4252', '--bg-sidebar': '#242933',
'--bg-hover': '#434c5e', '--border': '#4c566a', '--text-primary': '#eceff4',
'--text-secondary': '#d8dee9', '--text-muted': '#7b88a1', '--accent': '#88c0d0',
'--accent-green': '#a3be8c', '--tag-bg': '#2a3a48', '--tag-text': '#88c0d0',
'--code-bg': '#3b4252', '--search-bg': '#434c5e', '--scrollbar': '#4c566a',
'--resize-handle': '#4c566a', '--overlay-bg': 'rgba(0,0,0,0.6)',
'--danger': '#bf616a', '--danger-bg': '#3a2025', '--success': '#a3be8c', '--success-bg': '#1a2e1a',
'--accent-card': '#88c0d0', '--accent-bg': '#2a3a48', '--accent-text': '#88c0d0',
'--green': '#a3be8c', '--green-bg': '#1a2e1a', '--purple': '#b48ead', '--purple-bg': '#2a2030',
'--surface': '#3b4252', '--surface2': '#2e3440', '--surface3': '#242933',
'--border-md': '#4c566a', '--text': '#eceff4', '--text-2': '#d8dee9', '--text-3': '#7b88a1',
'--ok': '#a3be8c', '--warn': '#ebcb8b', '--ai': '#b48ead', '--err': '#bf616a'
},
light: {
'--bg-primary': '#eceff4', '--bg-secondary': '#e5e9f0', '--bg-sidebar': '#d8dee9',
'--bg-hover': '#d8dee9', '--border': '#c8cfdb', '--text-primary': '#2e3440',
'--text-secondary': '#4c566a', '--text-muted': '#7b88a1', '--accent': '#5e81ac',
'--accent-green': '#719350', '--tag-bg': '#dfe8f0', '--tag-text': '#5e81ac',
'--code-bg': '#e5e9f0', '--search-bg': '#eceff4', '--scrollbar': '#c8cfdb',
'--resize-handle': '#c8cfdb', '--overlay-bg': 'rgba(0,0,0,0.12)',
'--danger': '#bf616a', '--danger-bg': '#f8e0e0', '--success': '#719350', '--success-bg': '#e0f0d8',
'--accent-card': '#5e81ac', '--accent-bg': '#dfe8f0', '--accent-text': '#5e81ac',
'--green': '#719350', '--green-bg': '#e0f0d8', '--purple': '#7b5e95', '--purple-bg': '#e8dff0',
'--surface': '#e5e9f0', '--surface2': '#eceff4', '--surface3': '#d8dee9',
'--border-md': '#c8cfdb', '--text': '#2e3440', '--text-2': '#4c566a', '--text-3': '#7b88a1',
'--ok': '#719350', '--warn': '#8f6b20', '--ai': '#7b5e95', '--err': '#bf616a'
}
}
},
'night-owl': {
name: 'Night Owl', desc: 'Optimise pour la nuit',
modes: {
dark: {
'--bg-primary': '#011627', '--bg-secondary': '#01111d', '--bg-sidebar': '#010d18',
'--bg-hover': '#0b2942', '--border': '#1d3b53', '--text-primary': '#d6deeb',
'--text-secondary': '#7e97b0', '--text-muted': '#4b6479', '--accent': '#82aaff',
'--accent-green': '#c3e88d', '--tag-bg': '#152d45', '--tag-text': '#82aaff',
'--code-bg': '#01111d', '--search-bg': '#0b2942', '--scrollbar': '#1d3b53',
'--resize-handle': '#1d3b53', '--overlay-bg': 'rgba(0,0,0,0.7)',
'--danger': '#ef5350', '--danger-bg': '#2a1018', '--success': '#c3e88d', '--success-bg': '#0d2818',
'--accent-card': '#82aaff', '--accent-bg': '#152d45', '--accent-text': '#82aaff',
'--green': '#c3e88d', '--green-bg': '#0d2818', '--purple': '#c792ea', '--purple-bg': '#201838',
'--surface': '#01111d', '--surface2': '#011627', '--surface3': '#010d18',
'--border-md': '#1d3b53', '--text': '#d6deeb', '--text-2': '#7e97b0', '--text-3': '#4b6479',
'--ok': '#c3e88d', '--warn': '#ffcb8b', '--ai': '#c792ea', '--err': '#ef5350'
},
light: {
'--bg-primary': '#fbfbfb', '--bg-secondary': '#f0f0f0', '--bg-sidebar': '#e8e8e8',
'--bg-hover': '#e0e0e0', '--border': '#d4d4d4', '--text-primary': '#403f53',
'--text-secondary': '#5f6c7a', '--text-muted': '#8e99a8', '--accent': '#4876d6',
'--accent-green': '#2d8a4e', '--tag-bg': '#e0e8ff', '--tag-text': '#4876d6',
'--code-bg': '#f0f0f0', '--search-bg': '#fbfbfb', '--scrollbar': '#d4d4d4',
'--resize-handle': '#d4d4d4', '--overlay-bg': 'rgba(0,0,0,0.12)',
'--danger': '#c92a2a', '--danger-bg': '#ffe3e3', '--success': '#2d8a4e', '--success-bg': '#e0ffe0',
'--accent-card': '#4876d6', '--accent-bg': '#e0e8ff', '--accent-text': '#4876d6',
'--green': '#2d8a4e', '--green-bg': '#e0ffe0', '--purple': '#7c3aed', '--purple-bg': '#ede0ff',
'--surface': '#f0f0f0', '--surface2': '#fbfbfb', '--surface3': '#e8e8e8',
'--border-md': '#d4d4d4', '--text': '#403f53', '--text-2': '#5f6c7a', '--text-3': '#8e99a8',
'--ok': '#2d8a4e', '--warn': '#8f6b20', '--ai': '#7c3aed', '--err': '#c92a2a'
}
}
},
'anthracite': {
name: 'Anthracite', desc: 'Material dark',
modes: {
dark: {
'--bg-primary': '#1e1e1e', '--bg-secondary': '#252526', '--bg-sidebar': '#1a1a1a',
'--bg-hover': '#2d2d2d', '--border': '#3e3e3e', '--text-primary': '#d4d4d4',
'--text-secondary': '#9d9d9d', '--text-muted': '#6e6e6e', '--accent': '#9c7aef',
'--accent-green': '#6a9955', '--tag-bg': '#2a2250', '--tag-text': '#9c7aef',
'--code-bg': '#252526', '--search-bg': '#2d2d2d', '--scrollbar': '#3e3e3e',
'--resize-handle': '#3e3e3e', '--overlay-bg': 'rgba(0,0,0,0.7)',
'--danger': '#f44747', '--danger-bg': '#3a1a1a', '--success': '#6a9955', '--success-bg': '#1a2e1a',
'--accent-card': '#9c7aef', '--accent-bg': '#2a2250', '--accent-text': '#9c7aef',
'--green': '#6a9955', '--green-bg': '#1a2e1a', '--purple': '#9c7aef', '--purple-bg': '#2a2250',
'--surface': '#252526', '--surface2': '#1e1e1e', '--surface3': '#1a1a1a',
'--border-md': '#3e3e3e', '--text': '#d4d4d4', '--text-2': '#9d9d9d', '--text-3': '#6e6e6e',
'--ok': '#6a9955', '--warn': '#d7ba7d', '--ai': '#9c7aef', '--err': '#f44747'
},
light: {
'--bg-primary': '#fafafa', '--bg-secondary': '#f5f5f5', '--bg-sidebar': '#eeeeee',
'--bg-hover': '#e5e5e5', '--border': '#d5d5d5', '--text-primary': '#212121',
'--text-secondary': '#616161', '--text-muted': '#9e9e9e', '--accent': '#7c3aed',
'--accent-green': '#388e3c', '--tag-bg': '#ede0ff', '--tag-text': '#7c3aed',
'--code-bg': '#f5f5f5', '--search-bg': '#fafafa', '--scrollbar': '#d5d5d5',
'--resize-handle': '#d5d5d5', '--overlay-bg': 'rgba(0,0,0,0.12)',
'--danger': '#d32f2f', '--danger-bg': '#fde8e8', '--success': '#388e3c', '--success-bg': '#e8f5e9',
'--accent-card': '#7c3aed', '--accent-bg': '#ede0ff', '--accent-text': '#7c3aed',
'--green': '#388e3c', '--green-bg': '#e8f5e9', '--purple': '#7c3aed', '--purple-bg': '#ede0ff',
'--surface': '#f5f5f5', '--surface2': '#fafafa', '--surface3': '#eeeeee',
'--border-md': '#d5d5d5', '--text': '#212121', '--text-2': '#616161', '--text-3': '#9e9e9e',
'--ok': '#388e3c', '--warn': '#8f6b20', '--ai': '#7c3aed', '--err': '#d32f2f'
}
}
},
'cyberpunk': {
name: 'Cyberpunk', desc: 'Neon vibrant',
modes: {
dark: {
'--bg-primary': '#0a0a0f', '--bg-secondary': '#111122', '--bg-sidebar': '#08080d',
'--bg-hover': '#1a1a33', '--border': '#2a2a55', '--text-primary': '#e0e0ff',
'--text-secondary': '#8888cc', '--text-muted': '#555599', '--accent': '#00ffff',
'--accent-green': '#00ff88', '--tag-bg': '#0a2a3a', '--tag-text': '#00ffff',
'--code-bg': '#111122', '--search-bg': '#1a1a33', '--scrollbar': '#2a2a55',
'--resize-handle': '#2a2a55', '--overlay-bg': 'rgba(0,0,0,0.8)',
'--danger': '#ff3366', '--danger-bg': '#331122', '--success': '#00ff88', '--success-bg': '#003322',
'--accent-card': '#00ffff', '--accent-bg': '#0a2a3a', '--accent-text': '#00ffff',
'--green': '#00ff88', '--green-bg': '#003322', '--purple': '#ff00ff', '--purple-bg': '#220033',
'--surface': '#111122', '--surface2': '#0a0a0f', '--surface3': '#08080d',
'--border-md': '#2a2a55', '--text': '#e0e0ff', '--text-2': '#8888cc', '--text-3': '#555599',
'--ok': '#00ff88', '--warn': '#ffaa00', '--ai': '#ff00ff', '--err': '#ff3366'
},
light: {
'--bg-primary': '#f0f0ff', '--bg-secondary': '#e8e8ff', '--bg-sidebar': '#e0e0f8',
'--bg-hover': '#d8d8f0', '--border': '#c0c0e0', '--text-primary': '#1a1a33',
'--text-secondary': '#4a4a6a', '--text-muted': '#8080a0', '--accent': '#0077cc',
'--accent-green': '#008844', '--tag-bg': '#ddeeff', '--tag-text': '#0077cc',
'--code-bg': '#e8e8ff', '--search-bg': '#f0f0ff', '--scrollbar': '#c0c0e0',
'--resize-handle': '#c0c0e0', '--overlay-bg': 'rgba(0,0,0,0.1)',
'--danger': '#cc2244', '--danger-bg': '#ffe0e8', '--success': '#008844', '--success-bg': '#d8ffe0',
'--accent-card': '#0077cc', '--accent-bg': '#ddeeff', '--accent-text': '#0077cc',
'--green': '#008844', '--green-bg': '#d8ffe0', '--purple': '#8800cc', '--purple-bg': '#f0d8ff',
'--surface': '#e8e8ff', '--surface2': '#f0f0ff', '--surface3': '#e0e0f8',
'--border-md': '#c0c0e0', '--text': '#1a1a33', '--text-2': '#4a4a6a', '--text-3': '#8080a0',
'--ok': '#008844', '--warn': '#996600', '--ai': '#8800cc', '--err': '#cc2244'
}
}
},
'navy-elegance': {
name: 'Navy Elegance', desc: 'Bleu profond & or',
modes: {
dark: {
'--bg-primary': '#0a1628', '--bg-secondary': '#0d1f3c', '--bg-sidebar': '#081220',
'--bg-hover': '#162d50', '--border': '#1e3a5f', '--text-primary': '#d4dde8',
'--text-secondary': '#8899b4', '--text-muted': '#556688', '--accent': '#c9a84c',
'--accent-green': '#4caf7c', '--tag-bg': '#1e2840', '--tag-text': '#c9a84c',
'--code-bg': '#0d1f3c', '--search-bg': '#162d50', '--scrollbar': '#1e3a5f',
'--resize-handle': '#1e3a5f', '--overlay-bg': 'rgba(0,0,0,0.7)',
'--danger': '#d94a5a', '--danger-bg': '#351a22', '--success': '#4caf7c', '--success-bg': '#12281e',
'--accent-card': '#c9a84c', '--accent-bg': '#282218', '--accent-text': '#c9a84c',
'--green': '#4caf7c', '--green-bg': '#12281e', '--purple': '#8b6fc0', '--purple-bg': '#201a3a',
'--surface': '#0d1f3c', '--surface2': '#0a1628', '--surface3': '#081220',
'--border-md': '#1e3a5f', '--text': '#d4dde8', '--text-2': '#8899b4', '--text-3': '#556688',
'--ok': '#4caf7c', '--warn': '#c9a84c', '--ai': '#8b6fc0', '--err': '#d94a5a'
},
light: {
'--bg-primary': '#f5f0e8', '--bg-secondary': '#ede6d8', '--bg-sidebar': '#e8dfd0',
'--bg-hover': '#e0d8c8', '--border': '#c8bda8', '--text-primary': '#2a3a50',
'--text-secondary': '#5a6a80', '--text-muted': '#8a9aa8', '--accent': '#8b6914',
'--accent-green': '#3d7a4c', '--tag-bg': '#f0e8d0', '--tag-text': '#8b6914',
'--code-bg': '#ede6d8', '--search-bg': '#f5f0e8', '--scrollbar': '#c8bda8',
'--resize-handle': '#c8bda8', '--overlay-bg': 'rgba(0,0,0,0.1)',
'--danger': '#b8383a', '--danger-bg': '#f8e0e0', '--success': '#3d7a4c', '--success-bg': '#e0f0e0',
'--accent-card': '#8b6914', '--accent-bg': '#f0e8d0', '--accent-text': '#8b6914',
'--green': '#3d7a4c', '--green-bg': '#e0f0e0', '--purple': '#6a4c8a', '--purple-bg': '#e8dff0',
'--surface': '#ede6d8', '--surface2': '#f5f0e8', '--surface3': '#e8dfd0',
'--border-md': '#c8bda8', '--text': '#2a3a50', '--text-2': '#5a6a80', '--text-3': '#8a9aa8',
'--ok': '#3d7a4c', '--warn': '#8b6914', '--ai': '#6a4c8a', '--err': '#b8383a'
}
}
},
'tons-terreux': {
name: 'Tons Terreux', desc: 'Sensation organique',
modes: {
dark: {
'--bg-primary': '#1c1a16', '--bg-secondary': '#252218', '--bg-sidebar': '#161410',
'--bg-hover': '#302b20', '--border': '#3d3628', '--text-primary': '#e8e0d0',
'--text-secondary': '#a89880', '--text-muted': '#6b5d48', '--accent': '#c8a050',
'--accent-green': '#6b9b50', '--tag-bg': '#2a2418', '--tag-text': '#c8a050',
'--code-bg': '#252218', '--search-bg': '#302b20', '--scrollbar': '#3d3628',
'--resize-handle': '#3d3628', '--overlay-bg': 'rgba(0,0,0,0.7)',
'--danger': '#c86050', '--danger-bg': '#352018', '--success': '#6b9b50', '--success-bg': '#1a2a14',
'--accent-card': '#c8a050', '--accent-bg': '#2a2418', '--accent-text': '#c8a050',
'--green': '#6b9b50', '--green-bg': '#1a2a14', '--purple': '#9070b0', '--purple-bg': '#221a30',
'--surface': '#252218', '--surface2': '#1c1a16', '--surface3': '#161410',
'--border-md': '#3d3628', '--text': '#e8e0d0', '--text-2': '#a89880', '--text-3': '#6b5d48',
'--ok': '#6b9b50', '--warn': '#c8a050', '--ai': '#9070b0', '--err': '#c86050'
},
light: {
'--bg-primary': '#f8f4ec', '--bg-secondary': '#f0e8d8', '--bg-sidebar': '#e8e0d0',
'--bg-hover': '#e0d8c8', '--border': '#c8bda0', '--text-primary': '#3d3028',
'--text-secondary': '#6b5d48', '--text-muted': '#9a8a70', '--accent': '#8b6914',
'--accent-green': '#5a8440', '--tag-bg': '#f0e0c8', '--tag-text': '#8b6914',
'--code-bg': '#f0e8d8', '--search-bg': '#f8f4ec', '--scrollbar': '#c8bda0',
'--resize-handle': '#c8bda0', '--overlay-bg': 'rgba(0,0,0,0.1)',
'--danger': '#a84040', '--danger-bg': '#f8e0e0', '--success': '#5a8440', '--success-bg': '#e0f0d8',
'--accent-card': '#8b6914', '--accent-bg': '#f0e0c8', '--accent-text': '#8b6914',
'--green': '#5a8440', '--green-bg': '#e0f0d8', '--purple': '#7058a0', '--purple-bg': '#e8dff8',
'--surface': '#f0e8d8', '--surface2': '#f8f4ec', '--surface3': '#e8e0d0',
'--border-md': '#c8bda0', '--text': '#3d3028', '--text-2': '#6b5d48', '--text-3': '#9a8a70',
'--ok': '#5a8440', '--warn': '#8b6914', '--ai': '#7058a0', '--err': '#a84040'
}
}
}
};
// ── Theme Engine ─────────────────────────────────────────────────────
var _currentTheme = 'defaut-obsigate';
var _currentMode = 'dark';
var AVAILABLE_MODES = ['dark', 'light', 'high-contrast', 'sepia'];
// ── Mode generators ─────────────────────────────────────────────────
// Generate a high-contrast variant from dark-mode CSS vars.
function _genHighContrast(darkVars) {
return {
'--bg-primary': '#000000', '--bg-secondary': '#0a0a0a', '--bg-sidebar': '#000000',
'--bg-hover': '#141414', '--border': '#444444', '--text-primary': '#ffffff',
'--text-secondary': '#cccccc', '--text-muted': '#888888', '--accent': darkVars['--accent'] || '#58a6ff',
'--accent-green': '#4cff6e', '--tag-bg': '#1a2a44', '--tag-text': '#7dc4ff',
'--code-bg': '#0a0a0a', '--search-bg': '#111111', '--scrollbar': '#444444',
'--resize-handle': '#444444', '--overlay-bg': 'rgba(0,0,0,0.85)',
'--danger': '#ff6b6b', '--danger-bg': '#4a0f0f', '--success': '#4cff6e', '--success-bg': '#0a3a14',
'--accent-card': darkVars['--accent'] || '#58a6ff', '--accent-bg': '#1a2a44', '--accent-text': '#7dc4ff',
'--green': '#4cff6e', '--green-bg': '#0a3a14', '--purple': '#c084fc', '--purple-bg': '#2a1a4a',
'--surface': '#0a0a0a', '--surface2': '#000000', '--surface3': '#000000',
'--border-md': '#444444', '--text': '#ffffff', '--text-2': '#cccccc', '--text-3': '#888888',
'--ok': '#4cff6e', '--warn': '#ffcc00', '--ai': '#c084fc', '--err': '#ff6b6b'
};
}
// Generate a sepia variant from light-mode CSS vars.
function _genSepia(lightVars) {
return {
'--bg-primary': '#f5ecd5', '--bg-secondary': '#eee3c8', '--bg-sidebar': '#e8dcc0',
'--bg-hover': '#e0d4b4', '--border': '#c8b890', '--text-primary': '#3d2e1a',
'--text-secondary': '#6b5a3e', '--text-muted': '#9a8a6a', '--accent': '#b8860b',
'--accent-green': '#5a8a32', '--tag-bg': '#e8dcc0', '--tag-text': '#8b6914',
'--code-bg': '#eee3c8', '--search-bg': '#f5ecd5', '--scrollbar': '#c8b890',
'--resize-handle': '#c8b890', '--overlay-bg': 'rgba(60,40,10,0.25)',
'--danger': '#b33a2a', '--danger-bg': '#f5e0dc', '--success': '#5a8a32', '--success-bg': '#e0edd0',
'--accent-card': '#b8860b', '--accent-bg': '#f0e4c4', '--accent-text': '#8b6914',
'--green': '#5a8a32', '--green-bg': '#e0edd0', '--purple': '#7a5a9a', '--purple-bg': '#e8ddf0',
'--surface': '#eee3c8', '--surface2': '#f5ecd5', '--surface3': '#e8dcc0',
'--border-md': '#c8b890', '--text': '#3d2e1a', '--text-2': '#6b5a3e', '--text-3': '#9a8a6a',
'--ok': '#5a8a32', '--warn': '#b8860b', '--ai': '#7a5a9a', '--err': '#b33a2a'
};
}
// Get CSS vars for a theme + mode (generating HC/sepia on demand).
function _getVars(themeKey, mode) {
var theme = THEMES[themeKey];
if (!theme) return null;
if (theme.modes[mode]) return theme.modes[mode];
// Generate high-contrast / sepia from dark / light
if (mode === 'high-contrast') return _genHighContrast(theme.modes.dark || {});
if (mode === 'sepia') return _genSepia(theme.modes.light || {});
return null;
}
function applyTheme(themeKey, mode) {
var theme = THEMES[themeKey];
if (!theme) return;
mode = mode || _currentMode || 'dark';
var vars = _getVars(themeKey, mode);
if (!vars) return;
var root = document.documentElement;
Object.keys(vars).forEach(function(key) {
root.style.setProperty(key, vars[key]);
});
// Store resolved vars on the theme for export/preview
if (!theme.modes[mode]) theme.modes[mode] = vars;
_currentTheme = themeKey;
_currentMode = mode;
try { localStorage.setItem('obsigate-theme', themeKey); } catch(e) {}
try { localStorage.setItem('obsigate-theme-mode', mode); } catch(e) {}
// Notify other components of theme change
try {
root.setAttribute('data-theme', mode);
// Syntax highlighting follows the light/dark mode (BUG-078): the theme
// *key* is not a mode, so toggling the sheets by key used to disable both
// and strip every code block of its colours. Sepia/high-contrast reuse the
// light palette.
var darkSheet = document.getElementById('hljs-theme-dark');
var lightSheet = document.getElementById('hljs-theme-light');
if (darkSheet && lightSheet) {
var isDark = mode === 'dark';
darkSheet.disabled = !isDark;
lightSheet.disabled = isDark;
}
document.dispatchEvent(new CustomEvent('themechange', { detail: { theme: themeKey, mode: mode } }));
} catch(e) {}
}
function toggleThemeMode() {
var idx = AVAILABLE_MODES.indexOf(_currentMode);
var newMode = AVAILABLE_MODES[(idx + 1) % AVAILABLE_MODES.length];
applyTheme(_currentTheme, newMode);
return newMode;
}
function getCurrentTheme() { return _currentTheme; }
function getCurrentMode() { return _currentMode; }
// ── Public API ──────────────────────────────────────────────────────
function setTheme(name) {
if (THEMES[name]) {
applyTheme(name, _currentMode);
}
}
function getTheme() {
return _currentTheme;
}
function listThemes() {
return Object.keys(THEMES).map(function(key) {
return { id: key, name: THEMES[key].name, desc: THEMES[key].desc };
});
}
function listModes() {
return AVAILABLE_MODES.slice();
}
// ── Import / Export ─────────────────────────────────────────────────
function exportTheme(themeKey) {
themeKey = themeKey || _currentTheme;
var theme = THEMES[themeKey];
if (!theme) return null;
// Ensure HC/sepia are resolved for export
var modes = {};
AVAILABLE_MODES.forEach(function(m) {
modes[m] = _getVars(themeKey, m);
});
return JSON.stringify({
version: 1,
id: themeKey,
name: theme.name,
desc: theme.desc,
modes: modes
}, null, 2);
}
function exportAllThemes() {
var out = {};
Object.keys(THEMES).forEach(function(key) {
out[key] = {
name: THEMES[key].name,
desc: THEMES[key].desc,
modes: {}
};
AVAILABLE_MODES.forEach(function(m) {
out[key].modes[m] = _getVars(key, m);
});
});
return JSON.stringify({ version: 1, themes: out }, null, 2);
}
function importTheme(jsonStr) {
try {
var data = JSON.parse(jsonStr);
if (!data || !data.modes) return { ok: false, error: 'Invalid theme JSON: missing modes' };
var name = data.name || data.id || ('custom-' + Date.now());
var key = (data.id || name).toLowerCase().replace(/[^a-z0-9]+/g, '-');
var modes = {};
if (data.modes.dark && typeof data.modes.dark === 'object') modes.dark = data.modes.dark;
if (data.modes.light && typeof data.modes.light === 'object') modes.light = data.modes.light;
if (Object.keys(modes).length === 0) return { ok: false, error: 'Theme must define at least dark or light mode' };
THEMES[key] = { name: name, desc: data.desc || 'Custom theme', modes: modes };
try { localStorage.setItem('obsigate-custom-' + key, JSON.stringify(THEMES[key])); } catch(e) {}
return { ok: true, key: key };
} catch(e) {
return { ok: false, error: 'JSON parse error: ' + e.message };
}
}
function loadCustomThemes() {
var keys = [];
try {
for (var i = 0; i < localStorage.length; i++) {
var k = localStorage.key(i);
if (k && k.indexOf('obsigate-custom-') === 0) {
keys.push(k);
}
}
} catch(e) {}
keys.forEach(function(lsKey) {
try {
var data = JSON.parse(localStorage.getItem(lsKey));
if (data && data.modes) {
var key = lsKey.replace('obsigate-custom-', '');
THEMES[key] = data;
}
} catch(e) {}
});
}
function deleteCustomTheme(key) {
if (THEMES[key] && THEMES[key].desc === 'Custom theme') {
delete THEMES[key];
try { localStorage.removeItem('obsigate-custom-' + key); } catch(e) {}
return true;
}
return false;
}
function initThemes() {
// Load any custom themes from localStorage first
loadCustomThemes();
var saved = null;
var savedMode = null;
try { saved = localStorage.getItem('obsigate-theme'); } catch(e) {}
try { savedMode = localStorage.getItem('obsigate-theme-mode'); } catch(e) {}
if (saved && THEMES[saved]) _currentTheme = saved;
if (savedMode && AVAILABLE_MODES.indexOf(savedMode) !== -1) _currentMode = savedMode;
applyTheme(_currentTheme, _currentMode);
}
export {
THEMES, AVAILABLE_MODES,
applyTheme, toggleThemeMode,
getCurrentTheme, getCurrentMode,
getTheme,
setTheme, listThemes, listModes,
exportTheme, exportAllThemes, importTheme, deleteCustomTheme, loadCustomThemes,
initThemes
};