Merge branch 'auto-claude/056-add-design-system-themes-to-electron-app' into v2.6.0
This commit is contained in:
Generated
+29
-31
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "auto-claude-ui",
|
||||
"version": "2.3.0",
|
||||
"version": "2.5.0",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "auto-claude-ui",
|
||||
"version": "2.3.0",
|
||||
"version": "2.5.0",
|
||||
"hasInstallScript": true,
|
||||
"license": "AGPL-3.0",
|
||||
"dependencies": {
|
||||
@@ -150,7 +150,6 @@
|
||||
"integrity": "sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@babel/code-frame": "^7.27.1",
|
||||
"@babel/generator": "^7.28.5",
|
||||
@@ -536,7 +535,6 @@
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
},
|
||||
@@ -560,7 +558,6 @@
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
@@ -600,7 +597,6 @@
|
||||
"resolved": "https://registry.npmjs.org/@dnd-kit/core/-/core-6.3.1.tgz",
|
||||
"integrity": "sha512-xkGBRQQab4RLwgXxoqETICr6S5JlogafbhNsidmrkVv2YRs5MLwpjoF2qpiGjQt8S9AoxtIV603s0GIUpY5eYQ==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@dnd-kit/accessibility": "^3.1.1",
|
||||
"@dnd-kit/utilities": "^3.2.2",
|
||||
@@ -995,6 +991,7 @@
|
||||
"dev": true,
|
||||
"license": "BSD-2-Clause",
|
||||
"optional": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"cross-dirname": "^0.1.0",
|
||||
"debug": "^4.3.4",
|
||||
@@ -1016,6 +1013,7 @@
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"graceful-fs": "^4.2.0",
|
||||
"jsonfile": "^6.0.1",
|
||||
@@ -3930,7 +3928,8 @@
|
||||
"resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.4.tgz",
|
||||
"integrity": "sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
"license": "MIT",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/@types/babel__core": {
|
||||
"version": "7.20.5",
|
||||
@@ -4127,7 +4126,6 @@
|
||||
"resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.7.tgz",
|
||||
"integrity": "sha512-MWtvHrGZLFttgeEj28VXHxpmwYbor/ATPYbBfSFZEIRK0ecCFLl2Qo55z52Hss+UV9CRN7trSeq1zbgx7YDWWg==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"csstype": "^3.2.2"
|
||||
}
|
||||
@@ -4138,7 +4136,6 @@
|
||||
"integrity": "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==",
|
||||
"devOptional": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"peerDependencies": {
|
||||
"@types/react": "^19.2.0"
|
||||
}
|
||||
@@ -4230,7 +4227,6 @@
|
||||
"integrity": "sha512-N9lBGA9o9aqb1hVMc9hzySbhKibHmB+N3IpoShyV6HyQYRGIhlrO5rQgttypi+yEeKsKI4idxC8Jw6gXKD4THA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@typescript-eslint/scope-manager": "8.49.0",
|
||||
"@typescript-eslint/types": "8.49.0",
|
||||
@@ -4630,8 +4626,7 @@
|
||||
"version": "5.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@xterm/xterm/-/xterm-5.5.0.tgz",
|
||||
"integrity": "sha512-hqJHYaQb5OptNunnyAnkHyM8aCjZ1MEIDTQu1iIbbTD/xops91NB5yq1ZK/dC2JDbVWtF23zUtl9JE2NqwT87A==",
|
||||
"license": "MIT",
|
||||
"peer": true
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/7zip-bin": {
|
||||
"version": "5.2.0",
|
||||
@@ -4653,7 +4648,6 @@
|
||||
"integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"bin": {
|
||||
"acorn": "bin/acorn"
|
||||
},
|
||||
@@ -4714,7 +4708,6 @@
|
||||
"integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"fast-deep-equal": "^3.1.1",
|
||||
"fast-json-stable-stringify": "^2.0.0",
|
||||
@@ -4887,6 +4880,7 @@
|
||||
"integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"dequal": "^2.0.3"
|
||||
}
|
||||
@@ -5271,7 +5265,6 @@
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"baseline-browser-mapping": "^2.9.0",
|
||||
"caniuse-lite": "^1.0.30001759",
|
||||
@@ -5951,7 +5944,8 @@
|
||||
"integrity": "sha512-+R08/oI0nl3vfPcqftZRpytksBXDzOUveBq/NBVx0sUp1axwzPQrKinNx5yd5sxPu8j1wIy8AfnVQ+5eFdha6Q==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true
|
||||
"optional": true,
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/cross-spawn": {
|
||||
"version": "7.0.6",
|
||||
@@ -6295,7 +6289,6 @@
|
||||
"integrity": "sha512-59CAAjAhTaIMCN8y9kD573vDkxbs1uhDcrFLHSgutYdPcGOU35Rf95725snvzEOy4BFB7+eLJ8djCNPmGwG67w==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"app-builder-lib": "26.0.12",
|
||||
"builder-util": "26.0.11",
|
||||
@@ -6353,7 +6346,8 @@
|
||||
"resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz",
|
||||
"integrity": "sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
"license": "MIT",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/dotenv": {
|
||||
"version": "16.6.1",
|
||||
@@ -6429,7 +6423,6 @@
|
||||
"dev": true,
|
||||
"hasInstallScript": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@electron/get": "^2.0.0",
|
||||
"@types/node": "^22.7.7",
|
||||
@@ -6558,6 +6551,7 @@
|
||||
"dev": true,
|
||||
"hasInstallScript": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@electron/asar": "^3.2.1",
|
||||
"debug": "^4.1.1",
|
||||
@@ -6578,6 +6572,7 @@
|
||||
"integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"graceful-fs": "^4.1.2",
|
||||
"jsonfile": "^4.0.0",
|
||||
@@ -6593,6 +6588,7 @@
|
||||
"integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"optionalDependencies": {
|
||||
"graceful-fs": "^4.1.6"
|
||||
}
|
||||
@@ -6603,6 +6599,7 @@
|
||||
"integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">= 4.0.0"
|
||||
}
|
||||
@@ -6972,7 +6969,6 @@
|
||||
"integrity": "sha512-LEyamqS7W5HB3ujJyvi0HQK/dtVINZvd5mAAp9eT5S/ujByGjiZLCzPcHVzuXbpJDJF/cxwHlfceVUDZ2lnSTw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@eslint-community/eslint-utils": "^4.8.0",
|
||||
"@eslint-community/regexpp": "^4.12.1",
|
||||
@@ -8992,7 +8988,6 @@
|
||||
"integrity": "sha512-Cvc9WUhxSMEo4McES3P7oK3QaXldCfNWp7pl2NNeiIFlCoLr3kfq9kb1fxftiwk1FLV7CvpvDfonxtzUDeSOPg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"cssstyle": "^4.2.1",
|
||||
"data-urls": "^5.0.0",
|
||||
@@ -9936,6 +9931,7 @@
|
||||
"integrity": "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"bin": {
|
||||
"lz-string": "bin/bin.js"
|
||||
}
|
||||
@@ -11775,7 +11771,6 @@
|
||||
"integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
@@ -11873,7 +11868,6 @@
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"nanoid": "^3.3.11",
|
||||
"picocolors": "^1.1.1",
|
||||
@@ -11910,6 +11904,7 @@
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"commander": "^9.4.0"
|
||||
},
|
||||
@@ -11927,6 +11922,7 @@
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": "^12.20.0 || >=14"
|
||||
}
|
||||
@@ -11947,6 +11943,7 @@
|
||||
"integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"ansi-regex": "^5.0.1",
|
||||
"ansi-styles": "^5.0.0",
|
||||
@@ -11962,6 +11959,7 @@
|
||||
"integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
@@ -11974,7 +11972,8 @@
|
||||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
|
||||
"integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
"license": "MIT",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/proc-log": {
|
||||
"version": "2.0.1",
|
||||
@@ -12078,7 +12077,6 @@
|
||||
"resolved": "https://registry.npmjs.org/react/-/react-19.2.3.tgz",
|
||||
"integrity": "sha512-Ku/hhYbVjOQnXDZFv2+RibmLFGwFdeeKHFcOTlrt7xplBnya5OGn/hIRDsqDiSUcfORsDC7MPxwork8jBwsIWA==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
@@ -12088,7 +12086,6 @@
|
||||
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.3.tgz",
|
||||
"integrity": "sha512-yELu4WmLPw5Mr/lmeEpox5rw3RETacE++JgHqQzd2dg+YbJuat3jH4ingc+WPZhxaoFzdv9y33G+F7Nl5O0GBg==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"scheduler": "^0.27.0"
|
||||
},
|
||||
@@ -13405,8 +13402,7 @@
|
||||
"version": "4.1.18",
|
||||
"resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.18.tgz",
|
||||
"integrity": "sha512-4+Z+0yiYyEtUVCScyfHCxOYP06L5Ne+JiHhY2IjR2KWMIWhJOYZKLSGZaP5HkZ8+bY0cxfzwDE5uOmzFXyIwxw==",
|
||||
"license": "MIT",
|
||||
"peer": true
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/tapable": {
|
||||
"version": "2.3.0",
|
||||
@@ -13463,6 +13459,7 @@
|
||||
"integrity": "sha512-yYrrsWnrXMcdsnu/7YMYAofM1ktpL5By7vZhf15CrXijWWrEYZks5AXBudalfSWJLlnen/QUJUB5aoB0kqZUGA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"mkdirp": "^0.5.1",
|
||||
"rimraf": "~2.6.2"
|
||||
@@ -13489,6 +13486,7 @@
|
||||
"deprecated": "Glob versions prior to v9 are no longer supported",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"fs.realpath": "^1.0.0",
|
||||
"inflight": "^1.0.4",
|
||||
@@ -13510,6 +13508,7 @@
|
||||
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"brace-expansion": "^1.1.7"
|
||||
},
|
||||
@@ -13523,6 +13522,7 @@
|
||||
"integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"minimist": "^1.2.6"
|
||||
},
|
||||
@@ -13537,6 +13537,7 @@
|
||||
"deprecated": "Rimraf versions prior to v4 are no longer supported",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"glob": "^7.1.3"
|
||||
},
|
||||
@@ -13853,7 +13854,6 @@
|
||||
"integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"peer": true,
|
||||
"bin": {
|
||||
"tsc": "bin/tsc",
|
||||
"tsserver": "bin/tsserver"
|
||||
@@ -14194,7 +14194,6 @@
|
||||
"integrity": "sha512-dZwN5L1VlUBewiP6H9s2+B3e3Jg96D0vzN+Ry73sOefebhYr9f94wwkMNN/9ouoU8pV1BqA1d1zGk8928cx0rg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"esbuild": "^0.27.0",
|
||||
"fdir": "^6.5.0",
|
||||
@@ -15228,7 +15227,6 @@
|
||||
"integrity": "sha512-Bd5fw9wlIhtqCCxotZgdTOMwGm1a0u75wARVEY9HMs1X17trvA/lMi4+MGK5EUfYkXVTbX8UDiDKW4OgzHVUZw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/colinhacks"
|
||||
}
|
||||
|
||||
@@ -43,7 +43,8 @@ import { useTaskStore, loadTasks } from './stores/task-store';
|
||||
import { useSettingsStore, loadSettings } from './stores/settings-store';
|
||||
import { useTerminalStore, restoreTerminalSessions } from './stores/terminal-store';
|
||||
import { useIpcListeners } from './hooks/useIpc';
|
||||
import type { Task, Project } from '../shared/types';
|
||||
import { COLOR_THEMES } from '../shared/constants';
|
||||
import type { Task, Project, ColorTheme } from '../shared/types';
|
||||
|
||||
export function App() {
|
||||
// Load IPC listeners for real-time updates
|
||||
@@ -177,21 +178,38 @@ export function App() {
|
||||
|
||||
// Apply theme on load
|
||||
useEffect(() => {
|
||||
const root = document.documentElement;
|
||||
|
||||
const applyTheme = () => {
|
||||
// Apply light/dark mode
|
||||
if (settings.theme === 'dark') {
|
||||
document.documentElement.classList.add('dark');
|
||||
root.classList.add('dark');
|
||||
} else if (settings.theme === 'light') {
|
||||
document.documentElement.classList.remove('dark');
|
||||
root.classList.remove('dark');
|
||||
} else {
|
||||
// System preference
|
||||
if (window.matchMedia('(prefers-color-scheme: dark)').matches) {
|
||||
document.documentElement.classList.add('dark');
|
||||
root.classList.add('dark');
|
||||
} else {
|
||||
document.documentElement.classList.remove('dark');
|
||||
root.classList.remove('dark');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Apply color theme via data-theme attribute
|
||||
// Validate colorTheme against known themes, fallback to 'default' if invalid
|
||||
const validThemeIds = COLOR_THEMES.map((t) => t.id);
|
||||
const rawColorTheme = settings.colorTheme ?? 'default';
|
||||
const colorTheme: ColorTheme = validThemeIds.includes(rawColorTheme as ColorTheme)
|
||||
? (rawColorTheme as ColorTheme)
|
||||
: 'default';
|
||||
|
||||
if (colorTheme === 'default') {
|
||||
root.removeAttribute('data-theme');
|
||||
} else {
|
||||
root.setAttribute('data-theme', colorTheme);
|
||||
}
|
||||
|
||||
applyTheme();
|
||||
|
||||
// Listen for system theme changes
|
||||
@@ -206,7 +224,7 @@ export function App() {
|
||||
return () => {
|
||||
mediaQuery.removeEventListener('change', handleChange);
|
||||
};
|
||||
}, [settings.theme]);
|
||||
}, [settings.theme, settings.colorTheme]);
|
||||
|
||||
// Update selected task when tasks change (for real-time updates)
|
||||
useEffect(() => {
|
||||
|
||||
@@ -4,8 +4,6 @@ import {
|
||||
Plus,
|
||||
Settings,
|
||||
Trash2,
|
||||
Moon,
|
||||
Sun,
|
||||
LayoutGrid,
|
||||
Terminal,
|
||||
Map,
|
||||
@@ -53,7 +51,7 @@ import {
|
||||
checkProjectVersion,
|
||||
updateProjectAutoBuild
|
||||
} from '../stores/project-store';
|
||||
import { useSettingsStore, saveSettings } from '../stores/settings-store';
|
||||
import { useSettingsStore } from '../stores/settings-store';
|
||||
import { AddProjectModal } from './AddProjectModal';
|
||||
import { GitSetupModal } from './GitSetupModal';
|
||||
import { RateLimitIndicator } from './RateLimitIndicator';
|
||||
@@ -267,21 +265,6 @@ export function Sidebar({
|
||||
}
|
||||
};
|
||||
|
||||
const toggleTheme = () => {
|
||||
const newTheme = settings.theme === 'dark' ? 'light' : 'dark';
|
||||
saveSettings({ theme: newTheme });
|
||||
|
||||
if (newTheme === 'dark') {
|
||||
document.documentElement.classList.add('dark');
|
||||
} else {
|
||||
document.documentElement.classList.remove('dark');
|
||||
}
|
||||
};
|
||||
|
||||
const isDark =
|
||||
settings.theme === 'dark' ||
|
||||
(settings.theme === 'system' && window.matchMedia('(prefers-color-scheme: dark)').matches);
|
||||
|
||||
const handleNavClick = (view: SidebarView) => {
|
||||
onViewChange?.(view);
|
||||
};
|
||||
@@ -317,18 +300,8 @@ export function Sidebar({
|
||||
<TooltipProvider>
|
||||
<div className="flex h-full w-64 flex-col bg-sidebar border-r border-border">
|
||||
{/* Header with drag area - extra top padding for macOS traffic lights */}
|
||||
<div className="electron-drag flex h-14 items-center justify-between px-4 pt-6">
|
||||
<div className="electron-drag flex h-14 items-center px-4 pt-6">
|
||||
<span className="electron-no-drag text-lg font-bold text-primary">Auto Claude</span>
|
||||
<div className="electron-no-drag flex items-center gap-1">
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<Button variant="ghost" size="icon" onClick={toggleTheme}>
|
||||
{isDark ? <Sun className="h-4 w-4" /> : <Moon className="h-4 w-4" />}
|
||||
</Button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>Toggle theme</TooltipContent>
|
||||
</Tooltip>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Separator className="mt-2" />
|
||||
|
||||
@@ -77,7 +77,7 @@ const projectNavItems: NavItem<ProjectSettingsSection>[] = [
|
||||
* Coordinates app and project settings sections
|
||||
*/
|
||||
export function AppSettingsDialog({ open, onOpenChange, initialSection, initialProjectSection, onRerunWizard }: AppSettingsDialogProps) {
|
||||
const { settings, setSettings, isSaving, error, saveSettings } = useSettings();
|
||||
const { settings, setSettings, isSaving, error, saveSettings, revertTheme, commitTheme } = useSettings();
|
||||
const [version, setVersion] = useState<string>('');
|
||||
|
||||
// Track which top-level section is active
|
||||
@@ -138,10 +138,17 @@ export function AppSettingsDialog({ open, onOpenChange, initialSection, initialP
|
||||
}
|
||||
|
||||
if (appSaveSuccess) {
|
||||
// Commit the theme so future cancels won't revert to old values
|
||||
commitTheme();
|
||||
onOpenChange(false);
|
||||
}
|
||||
};
|
||||
|
||||
const handleCancel = () => {
|
||||
// onOpenChange handler will revert theme changes
|
||||
onOpenChange(false);
|
||||
};
|
||||
|
||||
const handleProjectChange = (projectId: string | null) => {
|
||||
selectProject(projectId);
|
||||
};
|
||||
@@ -183,7 +190,14 @@ export function AppSettingsDialog({ open, onOpenChange, initialSection, initialP
|
||||
const projectNavDisabled = !selectedProjectId;
|
||||
|
||||
return (
|
||||
<FullScreenDialog open={open} onOpenChange={onOpenChange}>
|
||||
<FullScreenDialog open={open} onOpenChange={(newOpen) => {
|
||||
if (!newOpen) {
|
||||
// Dialog is being closed (via X, escape, or overlay click)
|
||||
// Revert any unsaved theme changes
|
||||
revertTheme();
|
||||
}
|
||||
onOpenChange(newOpen);
|
||||
}}>
|
||||
<FullScreenDialogContent>
|
||||
<FullScreenDialogHeader>
|
||||
<FullScreenDialogTitle className="flex items-center gap-3">
|
||||
@@ -332,7 +346,7 @@ export function AppSettingsDialog({ open, onOpenChange, initialSection, initialP
|
||||
{error || projectError}
|
||||
</div>
|
||||
)}
|
||||
<Button variant="outline" onClick={() => onOpenChange(false)}>
|
||||
<Button variant="outline" onClick={handleCancel}>
|
||||
Cancel
|
||||
</Button>
|
||||
<Button
|
||||
|
||||
@@ -0,0 +1,138 @@
|
||||
import { Check, Sun, Moon, Monitor } from 'lucide-react';
|
||||
import { cn } from '../../lib/utils';
|
||||
import { Label } from '../ui/label';
|
||||
import { COLOR_THEMES } from '../../../shared/constants';
|
||||
import { useSettingsStore } from '../../stores/settings-store';
|
||||
import type { ColorTheme, AppSettings } from '../../../shared/types';
|
||||
|
||||
interface ThemeSelectorProps {
|
||||
settings: AppSettings;
|
||||
onSettingsChange: (settings: AppSettings) => void;
|
||||
}
|
||||
|
||||
/**
|
||||
* Theme selector component displaying a grid of theme cards with preview swatches
|
||||
* and a 3-option mode toggle (Light/Dark/System)
|
||||
*
|
||||
* Theme changes are applied immediately for live preview, while other settings
|
||||
* require saving to take effect.
|
||||
*/
|
||||
export function ThemeSelector({ settings, onSettingsChange }: ThemeSelectorProps) {
|
||||
const updateStoreSettings = useSettingsStore((state) => state.updateSettings);
|
||||
|
||||
const currentColorTheme = settings.colorTheme || 'default';
|
||||
const currentMode = settings.theme;
|
||||
const isDark = currentMode === 'dark' ||
|
||||
(currentMode === 'system' && window.matchMedia('(prefers-color-scheme: dark)').matches);
|
||||
|
||||
const handleColorThemeChange = (themeId: ColorTheme) => {
|
||||
// Update local draft state
|
||||
onSettingsChange({ ...settings, colorTheme: themeId });
|
||||
// Apply immediately to store for live preview (triggers App.tsx useEffect)
|
||||
updateStoreSettings({ colorTheme: themeId });
|
||||
};
|
||||
|
||||
const handleModeChange = (mode: 'light' | 'dark' | 'system') => {
|
||||
// Update local draft state
|
||||
onSettingsChange({ ...settings, theme: mode });
|
||||
// Apply immediately to store for live preview (triggers App.tsx useEffect)
|
||||
updateStoreSettings({ theme: mode });
|
||||
};
|
||||
|
||||
const getModeIcon = (mode: string) => {
|
||||
switch (mode) {
|
||||
case 'light':
|
||||
return <Sun className="h-4 w-4" />;
|
||||
case 'dark':
|
||||
return <Moon className="h-4 w-4" />;
|
||||
default:
|
||||
return <Monitor className="h-4 w-4" />;
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="space-y-6">
|
||||
{/* Mode Toggle */}
|
||||
<div className="space-y-3">
|
||||
<Label className="text-sm font-medium text-foreground">Appearance Mode</Label>
|
||||
<p className="text-sm text-muted-foreground">Choose light, dark, or system preference</p>
|
||||
<div className="grid grid-cols-3 gap-3 max-w-md pt-1">
|
||||
{(['system', 'light', 'dark'] as const).map((mode) => (
|
||||
<button
|
||||
key={mode}
|
||||
onClick={() => handleModeChange(mode)}
|
||||
className={cn(
|
||||
'flex flex-col items-center gap-2 p-4 rounded-lg border-2 transition-all',
|
||||
'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2',
|
||||
currentMode === mode
|
||||
? 'border-primary bg-primary/5'
|
||||
: 'border-border hover:border-primary/50 hover:bg-accent/50'
|
||||
)}
|
||||
>
|
||||
{getModeIcon(mode)}
|
||||
<span className="text-sm font-medium capitalize">{mode}</span>
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Color Theme Grid */}
|
||||
<div className="space-y-3">
|
||||
<Label className="text-sm font-medium text-foreground">Color Theme</Label>
|
||||
<p className="text-sm text-muted-foreground">Select a color palette for the interface</p>
|
||||
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-3 pt-1">
|
||||
{COLOR_THEMES.map((theme) => {
|
||||
const isSelected = currentColorTheme === theme.id;
|
||||
const bgColor = isDark ? theme.previewColors.darkBg : theme.previewColors.bg;
|
||||
const accentColor = isDark
|
||||
? (theme.previewColors.darkAccent || theme.previewColors.accent)
|
||||
: theme.previewColors.accent;
|
||||
|
||||
return (
|
||||
<button
|
||||
key={theme.id}
|
||||
onClick={() => handleColorThemeChange(theme.id)}
|
||||
className={cn(
|
||||
'relative flex flex-col p-4 rounded-lg border-2 text-left transition-all',
|
||||
'hover:shadow-md focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2',
|
||||
isSelected
|
||||
? 'border-primary bg-primary/5 shadow-sm'
|
||||
: 'border-border hover:border-primary/50 hover:bg-accent/30'
|
||||
)}
|
||||
>
|
||||
{/* Selection indicator */}
|
||||
{isSelected && (
|
||||
<div className="absolute top-2 right-2 w-5 h-5 rounded-full bg-primary flex items-center justify-center">
|
||||
<Check className="w-3 h-3 text-primary-foreground" />
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Preview swatches */}
|
||||
<div className="flex items-center gap-2 mb-3">
|
||||
<div className="flex -space-x-1.5">
|
||||
<div
|
||||
className="w-6 h-6 rounded-full border-2 border-background shadow-sm"
|
||||
style={{ backgroundColor: bgColor }}
|
||||
title="Background color"
|
||||
/>
|
||||
<div
|
||||
className="w-6 h-6 rounded-full border-2 border-background shadow-sm"
|
||||
style={{ backgroundColor: accentColor }}
|
||||
title="Accent color"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Theme info */}
|
||||
<div className="space-y-1">
|
||||
<p className="font-medium text-sm text-foreground">{theme.name}</p>
|
||||
<p className="text-xs text-muted-foreground line-clamp-2">{theme.description}</p>
|
||||
</div>
|
||||
</button>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,7 +1,5 @@
|
||||
import { Sun, Moon, Monitor } from 'lucide-react';
|
||||
import { Label } from '../ui/label';
|
||||
import { cn } from '../../lib/utils';
|
||||
import { SettingsSection } from './SettingsSection';
|
||||
import { ThemeSelector } from './ThemeSelector';
|
||||
import type { AppSettings } from '../../../shared/types';
|
||||
|
||||
interface ThemeSettingsProps {
|
||||
@@ -11,47 +9,15 @@ interface ThemeSettingsProps {
|
||||
|
||||
/**
|
||||
* Theme and appearance settings section
|
||||
* Wraps the ThemeSelector component with a consistent settings section layout
|
||||
*/
|
||||
export function ThemeSettings({ settings, onSettingsChange }: ThemeSettingsProps) {
|
||||
const getThemeIcon = (theme: string) => {
|
||||
switch (theme) {
|
||||
case 'light':
|
||||
return <Sun className="h-4 w-4" />;
|
||||
case 'dark':
|
||||
return <Moon className="h-4 w-4" />;
|
||||
default:
|
||||
return <Monitor className="h-4 w-4" />;
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<SettingsSection
|
||||
title="Appearance"
|
||||
description="Customize how Auto Claude looks"
|
||||
>
|
||||
<div className="space-y-4">
|
||||
<div className="space-y-3">
|
||||
<Label htmlFor="theme" className="text-sm font-medium text-foreground">Theme</Label>
|
||||
<p className="text-sm text-muted-foreground">Choose your preferred color scheme</p>
|
||||
<div className="grid grid-cols-3 gap-3">
|
||||
{(['system', 'light', 'dark'] as const).map((theme) => (
|
||||
<button
|
||||
key={theme}
|
||||
onClick={() => onSettingsChange({ ...settings, theme })}
|
||||
className={cn(
|
||||
'flex flex-col items-center gap-2 p-4 rounded-lg border-2 transition-all',
|
||||
settings.theme === theme
|
||||
? 'border-primary bg-primary/5'
|
||||
: 'border-border hover:border-primary/50 hover:bg-accent/50'
|
||||
)}
|
||||
>
|
||||
{getThemeIcon(theme)}
|
||||
<span className="text-sm font-medium capitalize">{theme}</span>
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<ThemeSelector settings={settings} onSettingsChange={onSettingsChange} />
|
||||
</SettingsSection>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,25 +1,41 @@
|
||||
import { useState, useEffect } from 'react';
|
||||
import { useState, useEffect, useRef, useCallback } from 'react';
|
||||
import { useSettingsStore, saveSettings as saveSettingsToStore, loadSettings as loadSettingsFromStore } from '../../../stores/settings-store';
|
||||
import type { AppSettings } from '../../../../shared/types';
|
||||
|
||||
/**
|
||||
* Custom hook for managing application settings
|
||||
* Provides state management and save/load functionality
|
||||
*
|
||||
* Theme changes are applied immediately for live preview. If the user cancels
|
||||
* without saving, call revertTheme() to restore the original theme.
|
||||
*/
|
||||
export function useSettings() {
|
||||
const currentSettings = useSettingsStore((state) => state.settings);
|
||||
const updateStoreSettings = useSettingsStore((state) => state.updateSettings);
|
||||
const [settings, setSettings] = useState<AppSettings>(currentSettings);
|
||||
const [isSaving, setIsSaving] = useState(false);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
|
||||
// Store the original theme settings when the hook mounts (dialog opens)
|
||||
// This allows us to revert if the user cancels
|
||||
const originalThemeRef = useRef<{ theme: AppSettings['theme']; colorTheme: AppSettings['colorTheme'] }>({
|
||||
theme: currentSettings.theme,
|
||||
colorTheme: currentSettings.colorTheme
|
||||
});
|
||||
|
||||
// Sync with store
|
||||
useEffect(() => {
|
||||
setSettings(currentSettings);
|
||||
}, [currentSettings]);
|
||||
|
||||
// Load settings on mount
|
||||
// Load settings on mount and capture original theme
|
||||
useEffect(() => {
|
||||
loadSettingsFromStore();
|
||||
// Update the original theme ref when settings load
|
||||
originalThemeRef.current = {
|
||||
theme: currentSettings.theme,
|
||||
colorTheme: currentSettings.colorTheme
|
||||
};
|
||||
}, []);
|
||||
|
||||
const saveSettings = async () => {
|
||||
@@ -63,6 +79,29 @@ export function useSettings() {
|
||||
setSettings((prev) => ({ ...prev, ...partial }));
|
||||
};
|
||||
|
||||
/**
|
||||
* Revert theme to the original values (before any preview changes).
|
||||
* Call this when the user cancels the settings dialog without saving.
|
||||
*/
|
||||
const revertTheme = useCallback(() => {
|
||||
const original = originalThemeRef.current;
|
||||
updateStoreSettings({
|
||||
theme: original.theme,
|
||||
colorTheme: original.colorTheme
|
||||
});
|
||||
}, [updateStoreSettings]);
|
||||
|
||||
/**
|
||||
* Capture the current theme as the new "original" after successful save.
|
||||
* This updates the reference point for future reverts.
|
||||
*/
|
||||
const commitTheme = useCallback(() => {
|
||||
originalThemeRef.current = {
|
||||
theme: settings.theme,
|
||||
colorTheme: settings.colorTheme
|
||||
};
|
||||
}, [settings.theme, settings.colorTheme]);
|
||||
|
||||
return {
|
||||
settings,
|
||||
setSettings,
|
||||
@@ -70,6 +109,8 @@ export function useSettings() {
|
||||
isSaving,
|
||||
error,
|
||||
saveSettings,
|
||||
applyTheme
|
||||
applyTheme,
|
||||
revertTheme,
|
||||
commitTheme
|
||||
};
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
export { AppSettingsDialog, type AppSection } from './AppSettings';
|
||||
export { ThemeSettings } from './ThemeSettings';
|
||||
export { ThemeSelector } from './ThemeSelector';
|
||||
export { GeneralSettings } from './GeneralSettings';
|
||||
export { IntegrationSettings } from './IntegrationSettings';
|
||||
export { AdvancedSettings } from './AdvancedSettings';
|
||||
|
||||
@@ -204,6 +204,810 @@
|
||||
--shadow-focus: 0 0 0 2px rgba(214, 216, 118, 0.2);
|
||||
}
|
||||
|
||||
/* ============================================
|
||||
DUSK THEME (Light)
|
||||
Warm, muted palette inspired by Fey/Oscura
|
||||
============================================ */
|
||||
[data-theme="dusk"] {
|
||||
/* Backgrounds */
|
||||
--background: #F5F5F0;
|
||||
--foreground: #131419;
|
||||
|
||||
/* Card surfaces */
|
||||
--card: #FFFFFF;
|
||||
--card-foreground: #131419;
|
||||
|
||||
/* Primary accent - muted olive/yellow */
|
||||
--primary: #B8B978;
|
||||
--primary-foreground: #131419;
|
||||
|
||||
/* Secondary */
|
||||
--secondary: #EAEAE5;
|
||||
--secondary-foreground: #131419;
|
||||
|
||||
/* Muted */
|
||||
--muted: #F0F0EB;
|
||||
--muted-foreground: #5C6974;
|
||||
|
||||
/* Accent */
|
||||
--accent: #F0F0E0;
|
||||
--accent-foreground: #B8B978;
|
||||
|
||||
/* Destructive */
|
||||
--destructive: #D84F68;
|
||||
--destructive-foreground: #FFFFFF;
|
||||
|
||||
/* Borders and inputs */
|
||||
--border: #E0E0DB;
|
||||
--input: #E0E0DB;
|
||||
--ring: #B8B978;
|
||||
|
||||
/* Sidebar */
|
||||
--sidebar: #FFFFFF;
|
||||
--sidebar-foreground: #131419;
|
||||
|
||||
/* Popover */
|
||||
--popover: #FFFFFF;
|
||||
--popover-foreground: #131419;
|
||||
|
||||
/* Semantic colors */
|
||||
--success: #4EBE96;
|
||||
--success-foreground: #FFFFFF;
|
||||
--success-light: #E0F5ED;
|
||||
--warning: #D2D714;
|
||||
--warning-foreground: #131419;
|
||||
--warning-light: #F5F5D0;
|
||||
--info: #479FFA;
|
||||
--info-foreground: #FFFFFF;
|
||||
--info-light: #E8F4FF;
|
||||
--error: #D84F68;
|
||||
--error-light: #FCE8EC;
|
||||
|
||||
/* Shadows */
|
||||
--shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
|
||||
--shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.07), 0 2px 4px -2px rgba(0, 0, 0, 0.05);
|
||||
--shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.08), 0 4px 6px -4px rgba(0, 0, 0, 0.05);
|
||||
--shadow-xl: 0 20px 25px -5px rgba(0, 0, 0, 0.08), 0 8px 10px -6px rgba(0, 0, 0, 0.04);
|
||||
--shadow-focus: 0 0 0 3px rgba(184, 185, 120, 0.2);
|
||||
}
|
||||
|
||||
/* ============================================
|
||||
DUSK THEME (Dark)
|
||||
Fey-inspired dark theme
|
||||
============================================ */
|
||||
[data-theme="dusk"].dark {
|
||||
/* Backgrounds */
|
||||
--background: #131419;
|
||||
--foreground: #E6E6E6;
|
||||
|
||||
/* Card surfaces */
|
||||
--card: #1A1B21;
|
||||
--card-foreground: #E6E6E6;
|
||||
|
||||
/* Primary accent - pale yellow */
|
||||
--primary: #E6E7A3;
|
||||
--primary-foreground: #131419;
|
||||
|
||||
/* Secondary */
|
||||
--secondary: #222329;
|
||||
--secondary-foreground: #E6E6E6;
|
||||
|
||||
/* Muted */
|
||||
--muted: #16171D;
|
||||
--muted-foreground: #868F97;
|
||||
|
||||
/* Accent */
|
||||
--accent: #2A2B1F;
|
||||
--accent-foreground: #E6E7A3;
|
||||
|
||||
/* Destructive */
|
||||
--destructive: #D84F68;
|
||||
--destructive-foreground: #131419;
|
||||
|
||||
/* Borders and inputs */
|
||||
--border: #282828;
|
||||
--input: #282828;
|
||||
--ring: #E6E7A3;
|
||||
|
||||
/* Sidebar */
|
||||
--sidebar: #16171D;
|
||||
--sidebar-foreground: #E6E6E6;
|
||||
|
||||
/* Popover */
|
||||
--popover: #222329;
|
||||
--popover-foreground: #E6E6E6;
|
||||
|
||||
/* Semantic colors */
|
||||
--success: #4EBE96;
|
||||
--success-foreground: #131419;
|
||||
--success-light: #1A2E28;
|
||||
--warning: #D2D714;
|
||||
--warning-foreground: #131419;
|
||||
--warning-light: #2A2B1A;
|
||||
--info: #479FFA;
|
||||
--info-foreground: #131419;
|
||||
--info-light: #1A2433;
|
||||
--error: #D84F68;
|
||||
--error-light: #2E1A1F;
|
||||
|
||||
/* Shadows */
|
||||
--shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.5);
|
||||
--shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.6);
|
||||
--shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.7);
|
||||
--shadow-xl: 0 20px 25px -5px rgba(0, 0, 0, 0.8);
|
||||
--shadow-focus: 0 0 0 2px rgba(230, 231, 163, 0.25);
|
||||
}
|
||||
|
||||
/* ============================================
|
||||
LIME THEME (Light)
|
||||
Fresh, energetic lime/chartreuse theme
|
||||
============================================ */
|
||||
[data-theme="lime"] {
|
||||
/* Backgrounds */
|
||||
--background: #E8F5A3;
|
||||
--foreground: #1A1A2E;
|
||||
|
||||
/* Card surfaces */
|
||||
--card: #FFFFFF;
|
||||
--card-foreground: #1A1A2E;
|
||||
|
||||
/* Primary accent - purple for contrast against lime */
|
||||
--primary: #7C3AED;
|
||||
--primary-foreground: #FFFFFF;
|
||||
|
||||
/* Secondary */
|
||||
--secondary: #F5F9E8;
|
||||
--secondary-foreground: #1A1A2E;
|
||||
|
||||
/* Muted */
|
||||
--muted: #F8FAFC;
|
||||
--muted-foreground: #64748B;
|
||||
|
||||
/* Accent */
|
||||
--accent: #EDE9FE;
|
||||
--accent-foreground: #7C3AED;
|
||||
|
||||
/* Destructive */
|
||||
--destructive: #DC2626;
|
||||
--destructive-foreground: #FFFFFF;
|
||||
|
||||
/* Borders and inputs */
|
||||
--border: #E2E8F0;
|
||||
--input: #E2E8F0;
|
||||
--ring: #7C3AED;
|
||||
|
||||
/* Sidebar */
|
||||
--sidebar: #FFFFFF;
|
||||
--sidebar-foreground: #1A1A2E;
|
||||
|
||||
/* Popover */
|
||||
--popover: #FFFFFF;
|
||||
--popover-foreground: #1A1A2E;
|
||||
|
||||
/* Semantic colors */
|
||||
--success: #059669;
|
||||
--success-foreground: #FFFFFF;
|
||||
--success-light: #D1FAE5;
|
||||
--warning: #D97706;
|
||||
--warning-foreground: #FFFFFF;
|
||||
--warning-light: #FEF3C7;
|
||||
--info: #2563EB;
|
||||
--info-foreground: #FFFFFF;
|
||||
--info-light: #DBEAFE;
|
||||
--error: #DC2626;
|
||||
--error-light: #FEE2E2;
|
||||
|
||||
/* Shadows */
|
||||
--shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
|
||||
--shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.07), 0 2px 4px -2px rgba(0, 0, 0, 0.05);
|
||||
--shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.08), 0 4px 6px -4px rgba(0, 0, 0, 0.05);
|
||||
--shadow-xl: 0 20px 25px -5px rgba(0, 0, 0, 0.08), 0 8px 10px -6px rgba(0, 0, 0, 0.04);
|
||||
--shadow-focus: 0 0 0 3px rgba(124, 58, 237, 0.2);
|
||||
}
|
||||
|
||||
/* ============================================
|
||||
LIME THEME (Dark)
|
||||
Fresh lime theme with deep purple undertones
|
||||
============================================ */
|
||||
[data-theme="lime"].dark {
|
||||
/* Backgrounds */
|
||||
--background: #0F0F1A;
|
||||
--foreground: #F8FAFC;
|
||||
|
||||
/* Card surfaces */
|
||||
--card: #1E1E2E;
|
||||
--card-foreground: #F8FAFC;
|
||||
|
||||
/* Primary accent - bright purple for dark mode */
|
||||
--primary: #8B5CF6;
|
||||
--primary-foreground: #0F0F1A;
|
||||
|
||||
/* Secondary */
|
||||
--secondary: #1A1A2E;
|
||||
--secondary-foreground: #F8FAFC;
|
||||
|
||||
/* Muted */
|
||||
--muted: #13131F;
|
||||
--muted-foreground: #A1A1B5;
|
||||
|
||||
/* Accent */
|
||||
--accent: #2E2350;
|
||||
--accent-foreground: #8B5CF6;
|
||||
|
||||
/* Destructive */
|
||||
--destructive: #F87171;
|
||||
--destructive-foreground: #0F0F1A;
|
||||
|
||||
/* Borders and inputs */
|
||||
--border: #2E2E40;
|
||||
--input: #2E2E40;
|
||||
--ring: #8B5CF6;
|
||||
|
||||
/* Sidebar */
|
||||
--sidebar: #13131F;
|
||||
--sidebar-foreground: #F8FAFC;
|
||||
|
||||
/* Popover */
|
||||
--popover: #262638;
|
||||
--popover-foreground: #F8FAFC;
|
||||
|
||||
/* Semantic colors */
|
||||
--success: #34D399;
|
||||
--success-foreground: #0F0F1A;
|
||||
--success-light: #134E4A;
|
||||
--warning: #FBBF24;
|
||||
--warning-foreground: #0F0F1A;
|
||||
--warning-light: #451A03;
|
||||
--info: #60A5FA;
|
||||
--info-foreground: #0F0F1A;
|
||||
--info-light: #1E3A8A;
|
||||
--error: #F87171;
|
||||
--error-light: #450A0A;
|
||||
|
||||
/* Shadows */
|
||||
--shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.5);
|
||||
--shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.6);
|
||||
--shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.7);
|
||||
--shadow-xl: 0 20px 25px -5px rgba(0, 0, 0, 0.8);
|
||||
--shadow-focus: 0 0 0 3px rgba(139, 92, 246, 0.3);
|
||||
}
|
||||
|
||||
/* ============================================
|
||||
OCEAN THEME (Light)
|
||||
Calm, professional blue tones
|
||||
============================================ */
|
||||
[data-theme="ocean"] {
|
||||
/* Backgrounds */
|
||||
--background: #E0F2FE;
|
||||
--foreground: #0C4A6E;
|
||||
|
||||
/* Card surfaces */
|
||||
--card: #FFFFFF;
|
||||
--card-foreground: #0C4A6E;
|
||||
|
||||
/* Primary accent - sky blue */
|
||||
--primary: #0284C7;
|
||||
--primary-foreground: #FFFFFF;
|
||||
|
||||
/* Secondary */
|
||||
--secondary: #F0F9FF;
|
||||
--secondary-foreground: #0C4A6E;
|
||||
|
||||
/* Muted */
|
||||
--muted: #F8FAFC;
|
||||
--muted-foreground: #64748B;
|
||||
|
||||
/* Accent */
|
||||
--accent: #E0F2FE;
|
||||
--accent-foreground: #0284C7;
|
||||
|
||||
/* Destructive */
|
||||
--destructive: #DC2626;
|
||||
--destructive-foreground: #FFFFFF;
|
||||
|
||||
/* Borders and inputs */
|
||||
--border: #BAE6FD;
|
||||
--input: #BAE6FD;
|
||||
--ring: #0284C7;
|
||||
|
||||
/* Sidebar */
|
||||
--sidebar: #FFFFFF;
|
||||
--sidebar-foreground: #0C4A6E;
|
||||
|
||||
/* Popover */
|
||||
--popover: #FFFFFF;
|
||||
--popover-foreground: #0C4A6E;
|
||||
|
||||
/* Semantic colors */
|
||||
--success: #059669;
|
||||
--success-foreground: #FFFFFF;
|
||||
--success-light: #D1FAE5;
|
||||
--warning: #D97706;
|
||||
--warning-foreground: #FFFFFF;
|
||||
--warning-light: #FEF3C7;
|
||||
--info: #2563EB;
|
||||
--info-foreground: #FFFFFF;
|
||||
--info-light: #DBEAFE;
|
||||
--error: #DC2626;
|
||||
--error-light: #FEE2E2;
|
||||
|
||||
/* Shadows */
|
||||
--shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
|
||||
--shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.07), 0 2px 4px -2px rgba(0, 0, 0, 0.05);
|
||||
--shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.08), 0 4px 6px -4px rgba(0, 0, 0, 0.05);
|
||||
--shadow-xl: 0 20px 25px -5px rgba(0, 0, 0, 0.08), 0 8px 10px -6px rgba(0, 0, 0, 0.04);
|
||||
--shadow-focus: 0 0 0 3px rgba(2, 132, 199, 0.2);
|
||||
}
|
||||
|
||||
/* ============================================
|
||||
OCEAN THEME (Dark)
|
||||
Deep ocean blue tones
|
||||
============================================ */
|
||||
[data-theme="ocean"].dark {
|
||||
/* Backgrounds */
|
||||
--background: #082F49;
|
||||
--foreground: #F0F9FF;
|
||||
|
||||
/* Card surfaces */
|
||||
--card: #164E63;
|
||||
--card-foreground: #F0F9FF;
|
||||
|
||||
/* Primary accent - bright sky blue */
|
||||
--primary: #38BDF8;
|
||||
--primary-foreground: #082F49;
|
||||
|
||||
/* Secondary */
|
||||
--secondary: #0C4A6E;
|
||||
--secondary-foreground: #F0F9FF;
|
||||
|
||||
/* Muted */
|
||||
--muted: #0A3D5C;
|
||||
--muted-foreground: #7DD3FC;
|
||||
|
||||
/* Accent */
|
||||
--accent: #0C4A6E;
|
||||
--accent-foreground: #38BDF8;
|
||||
|
||||
/* Destructive */
|
||||
--destructive: #F87171;
|
||||
--destructive-foreground: #082F49;
|
||||
|
||||
/* Borders and inputs */
|
||||
--border: #0E7490;
|
||||
--input: #0E7490;
|
||||
--ring: #38BDF8;
|
||||
|
||||
/* Sidebar */
|
||||
--sidebar: #0A3D5C;
|
||||
--sidebar-foreground: #F0F9FF;
|
||||
|
||||
/* Popover */
|
||||
--popover: #1E6B8A;
|
||||
--popover-foreground: #F0F9FF;
|
||||
|
||||
/* Semantic colors */
|
||||
--success: #34D399;
|
||||
--success-foreground: #082F49;
|
||||
--success-light: #134E4A;
|
||||
--warning: #FBBF24;
|
||||
--warning-foreground: #082F49;
|
||||
--warning-light: #451A03;
|
||||
--info: #60A5FA;
|
||||
--info-foreground: #082F49;
|
||||
--info-light: #1E3A8A;
|
||||
--error: #F87171;
|
||||
--error-light: #450A0A;
|
||||
|
||||
/* Shadows */
|
||||
--shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.5);
|
||||
--shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.6);
|
||||
--shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.7);
|
||||
--shadow-xl: 0 20px 25px -5px rgba(0, 0, 0, 0.8);
|
||||
--shadow-focus: 0 0 0 3px rgba(56, 189, 248, 0.3);
|
||||
}
|
||||
|
||||
/* ============================================
|
||||
RETRO THEME (Light)
|
||||
Warm, nostalgic amber/orange vibes
|
||||
============================================ */
|
||||
[data-theme="retro"] {
|
||||
/* Backgrounds */
|
||||
--background: #FEF3C7;
|
||||
--foreground: #78350F;
|
||||
|
||||
/* Card surfaces */
|
||||
--card: #FFFFFF;
|
||||
--card-foreground: #78350F;
|
||||
|
||||
/* Primary accent - warm amber/orange */
|
||||
--primary: #D97706;
|
||||
--primary-foreground: #FFFFFF;
|
||||
|
||||
/* Secondary */
|
||||
--secondary: #FFFBEB;
|
||||
--secondary-foreground: #78350F;
|
||||
|
||||
/* Muted */
|
||||
--muted: #FEFCE8;
|
||||
--muted-foreground: #92400E;
|
||||
|
||||
/* Accent */
|
||||
--accent: #FEF3C7;
|
||||
--accent-foreground: #D97706;
|
||||
|
||||
/* Destructive */
|
||||
--destructive: #B91C1C;
|
||||
--destructive-foreground: #FFFFFF;
|
||||
|
||||
/* Borders and inputs */
|
||||
--border: #FDE68A;
|
||||
--input: #FDE68A;
|
||||
--ring: #D97706;
|
||||
|
||||
/* Sidebar */
|
||||
--sidebar: #FFFFFF;
|
||||
--sidebar-foreground: #78350F;
|
||||
|
||||
/* Popover */
|
||||
--popover: #FFFFFF;
|
||||
--popover-foreground: #78350F;
|
||||
|
||||
/* Semantic colors */
|
||||
--success: #15803D;
|
||||
--success-foreground: #FFFFFF;
|
||||
--success-light: #DCFCE7;
|
||||
--warning: #CA8A04;
|
||||
--warning-foreground: #78350F;
|
||||
--warning-light: #FEF9C3;
|
||||
--info: #1D4ED8;
|
||||
--info-foreground: #FFFFFF;
|
||||
--info-light: #DBEAFE;
|
||||
--error: #B91C1C;
|
||||
--error-light: #FEE2E2;
|
||||
|
||||
/* Shadows */
|
||||
--shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
|
||||
--shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.07), 0 2px 4px -2px rgba(0, 0, 0, 0.05);
|
||||
--shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.08), 0 4px 6px -4px rgba(0, 0, 0, 0.05);
|
||||
--shadow-xl: 0 20px 25px -5px rgba(0, 0, 0, 0.08), 0 8px 10px -6px rgba(0, 0, 0, 0.04);
|
||||
--shadow-focus: 0 0 0 3px rgba(217, 119, 6, 0.2);
|
||||
}
|
||||
|
||||
/* ============================================
|
||||
RETRO THEME (Dark)
|
||||
Warm stone/brown tones with golden accents
|
||||
============================================ */
|
||||
[data-theme="retro"].dark {
|
||||
/* Backgrounds */
|
||||
--background: #1C1917;
|
||||
--foreground: #FEFCE8;
|
||||
|
||||
/* Card surfaces */
|
||||
--card: #44403C;
|
||||
--card-foreground: #FEFCE8;
|
||||
|
||||
/* Primary accent - bright amber/gold */
|
||||
--primary: #FBBF24;
|
||||
--primary-foreground: #1C1917;
|
||||
|
||||
/* Secondary */
|
||||
--secondary: #292524;
|
||||
--secondary-foreground: #FEFCE8;
|
||||
|
||||
/* Muted */
|
||||
--muted: #1C1917;
|
||||
--muted-foreground: #FDE68A;
|
||||
|
||||
/* Accent */
|
||||
--accent: #451A03;
|
||||
--accent-foreground: #FBBF24;
|
||||
|
||||
/* Destructive */
|
||||
--destructive: #F87171;
|
||||
--destructive-foreground: #1C1917;
|
||||
|
||||
/* Borders and inputs */
|
||||
--border: #78716C;
|
||||
--input: #78716C;
|
||||
--ring: #FBBF24;
|
||||
|
||||
/* Sidebar */
|
||||
--sidebar: #1C1917;
|
||||
--sidebar-foreground: #FEFCE8;
|
||||
|
||||
/* Popover */
|
||||
--popover: #57534E;
|
||||
--popover-foreground: #FEFCE8;
|
||||
|
||||
/* Semantic colors */
|
||||
--success: #4ADE80;
|
||||
--success-foreground: #1C1917;
|
||||
--success-light: #14532D;
|
||||
--warning: #FACC15;
|
||||
--warning-foreground: #1C1917;
|
||||
--warning-light: #422006;
|
||||
--info: #60A5FA;
|
||||
--info-foreground: #1C1917;
|
||||
--info-light: #1E3A8A;
|
||||
--error: #F87171;
|
||||
--error-light: #450A0A;
|
||||
|
||||
/* Shadows */
|
||||
--shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.5);
|
||||
--shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.6);
|
||||
--shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.7);
|
||||
--shadow-xl: 0 20px 25px -5px rgba(0, 0, 0, 0.8);
|
||||
--shadow-focus: 0 0 0 3px rgba(251, 191, 36, 0.3);
|
||||
}
|
||||
|
||||
/* ============================================
|
||||
NEO THEME (Light)
|
||||
Modern, cyberpunk-inspired pink/purple palette
|
||||
============================================ */
|
||||
[data-theme="neo"] {
|
||||
/* Backgrounds */
|
||||
--background: #FDF4FF;
|
||||
--foreground: #581C87;
|
||||
|
||||
/* Card surfaces */
|
||||
--card: #FFFFFF;
|
||||
--card-foreground: #581C87;
|
||||
|
||||
/* Primary accent - fuchsia/magenta */
|
||||
--primary: #D946EF;
|
||||
--primary-foreground: #FFFFFF;
|
||||
|
||||
/* Secondary */
|
||||
--secondary: #FAF5FF;
|
||||
--secondary-foreground: #581C87;
|
||||
|
||||
/* Muted */
|
||||
--muted: #F5F3FF;
|
||||
--muted-foreground: #7C3AED;
|
||||
|
||||
/* Accent */
|
||||
--accent: #FAE8FF;
|
||||
--accent-foreground: #D946EF;
|
||||
|
||||
/* Destructive */
|
||||
--destructive: #E11D48;
|
||||
--destructive-foreground: #FFFFFF;
|
||||
|
||||
/* Borders and inputs */
|
||||
--border: #F0ABFC;
|
||||
--input: #F0ABFC;
|
||||
--ring: #D946EF;
|
||||
|
||||
/* Sidebar */
|
||||
--sidebar: #FFFFFF;
|
||||
--sidebar-foreground: #581C87;
|
||||
|
||||
/* Popover */
|
||||
--popover: #FFFFFF;
|
||||
--popover-foreground: #581C87;
|
||||
|
||||
/* Semantic colors */
|
||||
--success: #06B6D4;
|
||||
--success-foreground: #FFFFFF;
|
||||
--success-light: #CFFAFE;
|
||||
--warning: #F59E0B;
|
||||
--warning-foreground: #581C87;
|
||||
--warning-light: #FEF3C7;
|
||||
--info: #8B5CF6;
|
||||
--info-foreground: #FFFFFF;
|
||||
--info-light: #EDE9FE;
|
||||
--error: #E11D48;
|
||||
--error-light: #FFE4E6;
|
||||
|
||||
/* Shadows */
|
||||
--shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
|
||||
--shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.07), 0 2px 4px -2px rgba(0, 0, 0, 0.05);
|
||||
--shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.08), 0 4px 6px -4px rgba(0, 0, 0, 0.05);
|
||||
--shadow-xl: 0 20px 25px -5px rgba(0, 0, 0, 0.08), 0 8px 10px -6px rgba(0, 0, 0, 0.04);
|
||||
--shadow-focus: 0 0 0 3px rgba(217, 70, 239, 0.2);
|
||||
}
|
||||
|
||||
/* ============================================
|
||||
NEO THEME (Dark)
|
||||
Cyberpunk dark mode with neon pink/purple glow
|
||||
============================================ */
|
||||
[data-theme="neo"].dark {
|
||||
/* Backgrounds */
|
||||
--background: #0F0720;
|
||||
--foreground: #FAF5FF;
|
||||
|
||||
/* Card surfaces */
|
||||
--card: #2D1B4E;
|
||||
--card-foreground: #FAF5FF;
|
||||
|
||||
/* Primary accent - bright pink/fuchsia */
|
||||
--primary: #F0ABFC;
|
||||
--primary-foreground: #0F0720;
|
||||
|
||||
/* Secondary */
|
||||
--secondary: #1A0A30;
|
||||
--secondary-foreground: #FAF5FF;
|
||||
|
||||
/* Muted */
|
||||
--muted: #150825;
|
||||
--muted-foreground: #E879F9;
|
||||
|
||||
/* Accent */
|
||||
--accent: #581C87;
|
||||
--accent-foreground: #F0ABFC;
|
||||
|
||||
/* Destructive */
|
||||
--destructive: #FB7185;
|
||||
--destructive-foreground: #0F0720;
|
||||
|
||||
/* Borders and inputs */
|
||||
--border: #581C87;
|
||||
--input: #581C87;
|
||||
--ring: #F0ABFC;
|
||||
|
||||
/* Sidebar */
|
||||
--sidebar: #150825;
|
||||
--sidebar-foreground: #FAF5FF;
|
||||
|
||||
/* Popover */
|
||||
--popover: #3D2563;
|
||||
--popover-foreground: #FAF5FF;
|
||||
|
||||
/* Semantic colors */
|
||||
--success: #22D3EE;
|
||||
--success-foreground: #0F0720;
|
||||
--success-light: #164E63;
|
||||
--warning: #FBBF24;
|
||||
--warning-foreground: #0F0720;
|
||||
--warning-light: #451A03;
|
||||
--info: #A78BFA;
|
||||
--info-foreground: #0F0720;
|
||||
--info-light: #4C1D95;
|
||||
--error: #FB7185;
|
||||
--error-light: #4C0519;
|
||||
|
||||
/* Shadows - with subtle neon glow effect */
|
||||
--shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.4), 0 0 20px rgba(217, 70, 239, 0.1);
|
||||
--shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.5), 0 0 30px rgba(217, 70, 239, 0.1);
|
||||
--shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.6), 0 0 40px rgba(217, 70, 239, 0.15);
|
||||
--shadow-xl: 0 20px 25px -5px rgba(0, 0, 0, 0.6), 0 0 50px rgba(217, 70, 239, 0.2);
|
||||
--shadow-focus: 0 0 0 3px rgba(240, 171, 252, 0.4);
|
||||
}
|
||||
|
||||
/* ============================================
|
||||
FOREST THEME (Light)
|
||||
Natural, earthy green tones
|
||||
============================================ */
|
||||
[data-theme="forest"] {
|
||||
/* Backgrounds */
|
||||
--background: #DCFCE7;
|
||||
--foreground: #14532D;
|
||||
|
||||
/* Card surfaces */
|
||||
--card: #FFFFFF;
|
||||
--card-foreground: #14532D;
|
||||
|
||||
/* Primary accent - natural green */
|
||||
--primary: #16A34A;
|
||||
--primary-foreground: #FFFFFF;
|
||||
|
||||
/* Secondary */
|
||||
--secondary: #F0FDF4;
|
||||
--secondary-foreground: #14532D;
|
||||
|
||||
/* Muted */
|
||||
--muted: #ECFDF5;
|
||||
--muted-foreground: #166534;
|
||||
|
||||
/* Accent */
|
||||
--accent: #DCFCE7;
|
||||
--accent-foreground: #16A34A;
|
||||
|
||||
/* Destructive */
|
||||
--destructive: #DC2626;
|
||||
--destructive-foreground: #FFFFFF;
|
||||
|
||||
/* Borders and inputs */
|
||||
--border: #86EFAC;
|
||||
--input: #86EFAC;
|
||||
--ring: #16A34A;
|
||||
|
||||
/* Sidebar */
|
||||
--sidebar: #FFFFFF;
|
||||
--sidebar-foreground: #14532D;
|
||||
|
||||
/* Popover */
|
||||
--popover: #FFFFFF;
|
||||
--popover-foreground: #14532D;
|
||||
|
||||
/* Semantic colors */
|
||||
--success: #059669;
|
||||
--success-foreground: #FFFFFF;
|
||||
--success-light: #D1FAE5;
|
||||
--warning: #CA8A04;
|
||||
--warning-foreground: #14532D;
|
||||
--warning-light: #FEF9C3;
|
||||
--info: #0284C7;
|
||||
--info-foreground: #FFFFFF;
|
||||
--info-light: #E0F2FE;
|
||||
--error: #DC2626;
|
||||
--error-light: #FEE2E2;
|
||||
|
||||
/* Shadows */
|
||||
--shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
|
||||
--shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.07), 0 2px 4px -2px rgba(0, 0, 0, 0.05);
|
||||
--shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.08), 0 4px 6px -4px rgba(0, 0, 0, 0.05);
|
||||
--shadow-xl: 0 20px 25px -5px rgba(0, 0, 0, 0.08), 0 8px 10px -6px rgba(0, 0, 0, 0.04);
|
||||
--shadow-focus: 0 0 0 3px rgba(22, 163, 74, 0.2);
|
||||
}
|
||||
|
||||
/* ============================================
|
||||
FOREST THEME (Dark)
|
||||
Deep forest green tones with bright green accents
|
||||
============================================ */
|
||||
[data-theme="forest"].dark {
|
||||
/* Backgrounds */
|
||||
--background: #052E16;
|
||||
--foreground: #F0FDF4;
|
||||
|
||||
/* Card surfaces */
|
||||
--card: #166534;
|
||||
--card-foreground: #F0FDF4;
|
||||
|
||||
/* Primary accent - bright green for dark mode */
|
||||
--primary: #4ADE80;
|
||||
--primary-foreground: #052E16;
|
||||
|
||||
/* Secondary */
|
||||
--secondary: #14532D;
|
||||
--secondary-foreground: #F0FDF4;
|
||||
|
||||
/* Muted */
|
||||
--muted: #0A3D1F;
|
||||
--muted-foreground: #86EFAC;
|
||||
|
||||
/* Accent */
|
||||
--accent: #14532D;
|
||||
--accent-foreground: #4ADE80;
|
||||
|
||||
/* Destructive */
|
||||
--destructive: #F87171;
|
||||
--destructive-foreground: #052E16;
|
||||
|
||||
/* Borders and inputs */
|
||||
--border: #166534;
|
||||
--input: #166534;
|
||||
--ring: #4ADE80;
|
||||
|
||||
/* Sidebar */
|
||||
--sidebar: #0A3D1F;
|
||||
--sidebar-foreground: #F0FDF4;
|
||||
|
||||
/* Popover */
|
||||
--popover: #15803D;
|
||||
--popover-foreground: #F0FDF4;
|
||||
|
||||
/* Semantic colors */
|
||||
--success: #34D399;
|
||||
--success-foreground: #052E16;
|
||||
--success-light: #064E3B;
|
||||
--warning: #FBBF24;
|
||||
--warning-foreground: #052E16;
|
||||
--warning-light: #451A03;
|
||||
--info: #38BDF8;
|
||||
--info-foreground: #052E16;
|
||||
--info-light: #0C4A6E;
|
||||
--error: #F87171;
|
||||
--error-light: #450A0A;
|
||||
|
||||
/* Shadows */
|
||||
--shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.5);
|
||||
--shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.6);
|
||||
--shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.7);
|
||||
--shadow-xl: 0 20px 25px -5px rgba(0, 0, 0, 0.8);
|
||||
--shadow-focus: 0 0 0 3px rgba(74, 222, 128, 0.3);
|
||||
}
|
||||
|
||||
/* Base styles */
|
||||
* {
|
||||
border-color: var(--border);
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
|
||||
export const DEFAULT_APP_SETTINGS = {
|
||||
theme: 'system' as const,
|
||||
colorTheme: 'default' as const,
|
||||
defaultModel: 'opus',
|
||||
agentFramework: 'auto-claude',
|
||||
pythonPath: undefined as string | undefined,
|
||||
|
||||
@@ -21,6 +21,9 @@ export * from './changelog';
|
||||
// Model and agent profile constants
|
||||
export * from './models';
|
||||
|
||||
// Theme constants
|
||||
export * from './themes';
|
||||
|
||||
// GitHub integration constants
|
||||
export * from './github';
|
||||
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
/**
|
||||
* Theme constants
|
||||
* Color themes for multi-theme support with light/dark mode variants
|
||||
*/
|
||||
|
||||
import type { ColorThemeDefinition } from '../types/settings';
|
||||
|
||||
// ============================================
|
||||
// Color Themes
|
||||
// ============================================
|
||||
|
||||
/**
|
||||
* All available color themes with preview colors for the theme selector.
|
||||
* Each theme has both light and dark mode variants defined in CSS.
|
||||
*/
|
||||
export const COLOR_THEMES: ColorThemeDefinition[] = [
|
||||
{
|
||||
id: 'default',
|
||||
name: 'Default',
|
||||
description: 'Oscura-inspired with pale yellow accent',
|
||||
previewColors: { bg: '#F2F2ED', accent: '#E6E7A3', darkBg: '#0B0B0F', darkAccent: '#E6E7A3' }
|
||||
},
|
||||
{
|
||||
id: 'dusk',
|
||||
name: 'Dusk',
|
||||
description: 'Warmer variant with slightly lighter dark mode',
|
||||
previewColors: { bg: '#F5F5F0', accent: '#E6E7A3', darkBg: '#131419', darkAccent: '#E6E7A3' }
|
||||
},
|
||||
{
|
||||
id: 'lime',
|
||||
name: 'Lime',
|
||||
description: 'Fresh, energetic lime with purple accents',
|
||||
previewColors: { bg: '#E8F5A3', accent: '#7C3AED', darkBg: '#0F0F1A' }
|
||||
},
|
||||
{
|
||||
id: 'ocean',
|
||||
name: 'Ocean',
|
||||
description: 'Calm, professional blue tones',
|
||||
previewColors: { bg: '#E0F2FE', accent: '#0284C7', darkBg: '#082F49' }
|
||||
},
|
||||
{
|
||||
id: 'retro',
|
||||
name: 'Retro',
|
||||
description: 'Warm, nostalgic amber vibes',
|
||||
previewColors: { bg: '#FEF3C7', accent: '#D97706', darkBg: '#1C1917' }
|
||||
},
|
||||
{
|
||||
id: 'neo',
|
||||
name: 'Neo',
|
||||
description: 'Modern cyberpunk pink/magenta',
|
||||
previewColors: { bg: '#FDF4FF', accent: '#D946EF', darkBg: '#0F0720' }
|
||||
},
|
||||
{
|
||||
id: 'forest',
|
||||
name: 'Forest',
|
||||
description: 'Natural, earthy green tones',
|
||||
previewColors: { bg: '#DCFCE7', accent: '#16A34A', darkBg: '#052E16' }
|
||||
}
|
||||
];
|
||||
@@ -5,6 +5,23 @@
|
||||
import type { NotificationSettings } from './project';
|
||||
import type { ChangelogFormat, ChangelogAudience, ChangelogEmojiLevel } from './changelog';
|
||||
|
||||
// Color theme types for multi-theme support
|
||||
export type ColorTheme = 'default' | 'dusk' | 'lime' | 'ocean' | 'retro' | 'neo' | 'forest';
|
||||
|
||||
export interface ThemePreviewColors {
|
||||
bg: string;
|
||||
accent: string;
|
||||
darkBg: string;
|
||||
darkAccent?: string;
|
||||
}
|
||||
|
||||
export interface ColorThemeDefinition {
|
||||
id: ColorTheme;
|
||||
name: string;
|
||||
description: string;
|
||||
previewColors: ThemePreviewColors;
|
||||
}
|
||||
|
||||
// Thinking level for Claude model (budget token allocation)
|
||||
export type ThinkingLevel = 'none' | 'low' | 'medium' | 'high' | 'ultrathink';
|
||||
|
||||
@@ -44,6 +61,7 @@ export interface AgentProfile {
|
||||
|
||||
export interface AppSettings {
|
||||
theme: 'light' | 'dark' | 'system';
|
||||
colorTheme?: ColorTheme;
|
||||
defaultModel: string;
|
||||
agentFramework: string;
|
||||
pythonPath?: string;
|
||||
|
||||
Reference in New Issue
Block a user