From 0746844d6fe6800c30699005b7170aea2280e47f Mon Sep 17 00:00:00 2001 From: Andre Padez Date: Tue, 17 Feb 2026 18:46:18 +0000 Subject: [PATCH] extracted terminal to a widget --- bun.lock | 12 +- package.json | 2 +- src/apps/officer-web/App.tsx | 59 ++-- .../Screens/Dashboard/Chat/ChatList/index.tsx | 9 +- .../Screens/Dashboard/Chat/index.tsx | 39 +-- .../Screens/Dashboard/Home/index.tsx | 26 +- .../{Layout.tsx => Layout.backup.tsx} | 0 .../Dashboard/Layout/AuthenticationLayout.tsx | 21 -- .../Screens/Dashboard/Layout/Background.tsx | 2 - .../Dashboard/Layout/DashboardLayout.tsx | 24 ++ .../Screens/Dashboard/{ => Layout}/Dock.tsx | 17 +- .../Layout/DuckAvatar/DebugPanel.tsx | 43 --- .../Layout/DuckAvatar/DuckAvatar.tsx | 118 ------- .../Dashboard/Layout/DuckAvatar/DuckModel.tsx | 68 ---- .../Dashboard/Layout/DuckAvatar/index.tsx | 1 - .../Dashboard/Layout/Header/Header.tsx | 25 ++ .../Dashboard/Layout/Header/UserMenu.tsx | 59 ++++ .../Screens/Dashboard/Layout/Header/index.tsx | 1 + .../Screens/Dashboard/Layout/index.tsx | 2 +- .../Dashboard/OnboardingAdmin/index.tsx | 17 +- .../Screens/Dashboard/Plans/index.tsx | 8 +- .../Screens/Dashboard/ResourcePage.tsx | 6 +- .../Screens/Dashboard/Settings/AISettings.tsx | 11 +- .../Settings/ProfileSettings/index.tsx | 89 +++-- .../Settings/ResourceSettings/index.tsx | 7 +- .../Settings/ServerSettings/index.tsx | 93 +++--- .../Screens/Dashboard/Settings/index.tsx | 33 +- .../Screens/Dashboard/TaskLogs/index.tsx | 7 +- .../Screens/Dashboard/Terminal/index.tsx | 5 + .../officer-web/Screens/Dashboard/index.tsx | 13 + src/apps/officer-web/frontend.tsx | 12 - src/apps/officer-web/state/useThemeSync.ts | 37 +-- src/apps/officer-web/styles/globals.css | 163 +++++++++ src/apps/officer-web/styles/index.css | 1 + .../officer-web/styles}/prose.css | 0 src/server.tsx | 2 +- .../api/terminal}/Dockerfile.terminal-sidecar | 0 .../api/terminal}/pty-sidecar.mjs | 0 .../api/terminal}/templates/.zshrc | 0 .../terminal}/templates/starship-officer.toml | 0 .../api/terminal}/websocket.ts | 6 + .../plugins/Terminal/TERMINAL_PLUGIN.md | 308 ------------------ .../plugins/Terminal/client/Screen/index.tsx | 10 - .../plugins/Terminal/client/index.ts | 2 - src/workspaces/plugins/Terminal/index.ts | 8 - .../plugins/Terminal/server/index.ts | 1 - src/workspaces/plugins/package.json | 3 - .../themes/CatppuccinLatte/client.ts | 2 - .../themes/CatppuccinLatte/index.ts | 1 - .../themes/CatppuccinLatte/prose.css | 124 ------- .../themes/CatppuccinLatte/variables.css | 92 ------ .../themes/CatppuccinMocha/client.ts | 2 - .../themes/CatppuccinMocha/index.ts | 1 - .../themes/CatppuccinMocha/prose.css | 124 ------- .../themes/CatppuccinMocha/variables.css | 92 ------ src/workspaces/themes/DuckPond/client.ts | 4 - src/workspaces/themes/DuckPond/index.ts | 1 - src/workspaces/themes/DuckPond/variables.css | 164 ---------- src/workspaces/themes/Everforest/client.ts | 2 - src/workspaces/themes/Everforest/index.ts | 1 - src/workspaces/themes/Everforest/prose.css | 124 ------- .../themes/Everforest/variables.css | 92 ------ src/workspaces/themes/Gruvbox/client.ts | 2 - src/workspaces/themes/Gruvbox/index.ts | 1 - src/workspaces/themes/Gruvbox/prose.css | 124 ------- src/workspaces/themes/Gruvbox/variables.css | 92 ------ src/workspaces/themes/Kanagawa/client.ts | 2 - src/workspaces/themes/Kanagawa/index.ts | 1 - src/workspaces/themes/Kanagawa/prose.css | 124 ------- src/workspaces/themes/Kanagawa/variables.css | 92 ------ src/workspaces/themes/MatteBlack/client.ts | 2 - src/workspaces/themes/MatteBlack/index.ts | 1 - src/workspaces/themes/MatteBlack/prose.css | 124 ------- .../themes/MatteBlack/variables.css | 92 ------ src/workspaces/themes/Nord/client.ts | 2 - src/workspaces/themes/Nord/index.ts | 1 - src/workspaces/themes/Nord/prose.css | 124 ------- src/workspaces/themes/Nord/variables.css | 92 ------ src/workspaces/themes/OsakaJade/client.ts | 2 - src/workspaces/themes/OsakaJade/index.ts | 1 - src/workspaces/themes/OsakaJade/prose.css | 124 ------- src/workspaces/themes/OsakaJade/variables.css | 92 ------ src/workspaces/themes/Ristretto/client.ts | 2 - src/workspaces/themes/Ristretto/index.ts | 1 - src/workspaces/themes/Ristretto/prose.css | 124 ------- src/workspaces/themes/Ristretto/variables.css | 92 ------ src/workspaces/themes/RosePine/client.ts | 2 - src/workspaces/themes/RosePine/index.ts | 1 - src/workspaces/themes/RosePine/prose.css | 124 ------- src/workspaces/themes/RosePine/variables.css | 92 ------ src/workspaces/themes/TokyoNight/client.ts | 2 - src/workspaces/themes/TokyoNight/index.ts | 1 - src/workspaces/themes/TokyoNight/prose.css | 124 ------- .../themes/TokyoNight/variables.css | 92 ------ src/workspaces/themes/index.ts | 14 - src/workspaces/themes/package.json | 31 -- .../client => widgets}/TerminalView.tsx | 0 src/workspaces/widgets/package.json | 7 + 98 files changed, 487 insertions(+), 3513 deletions(-) rename src/apps/officer-web/Screens/Dashboard/{Layout.tsx => Layout.backup.tsx} (100%) delete mode 100644 src/apps/officer-web/Screens/Dashboard/Layout/AuthenticationLayout.tsx create mode 100644 src/apps/officer-web/Screens/Dashboard/Layout/DashboardLayout.tsx rename src/apps/officer-web/Screens/Dashboard/{ => Layout}/Dock.tsx (75%) delete mode 100644 src/apps/officer-web/Screens/Dashboard/Layout/DuckAvatar/DebugPanel.tsx delete mode 100644 src/apps/officer-web/Screens/Dashboard/Layout/DuckAvatar/DuckAvatar.tsx delete mode 100644 src/apps/officer-web/Screens/Dashboard/Layout/DuckAvatar/DuckModel.tsx delete mode 100644 src/apps/officer-web/Screens/Dashboard/Layout/DuckAvatar/index.tsx create mode 100644 src/apps/officer-web/Screens/Dashboard/Layout/Header/Header.tsx create mode 100644 src/apps/officer-web/Screens/Dashboard/Layout/Header/UserMenu.tsx create mode 100644 src/apps/officer-web/Screens/Dashboard/Layout/Header/index.tsx create mode 100644 src/apps/officer-web/Screens/Dashboard/Terminal/index.tsx create mode 100644 src/apps/officer-web/Screens/Dashboard/index.tsx rename src/{workspaces/themes/DuckPond => apps/officer-web/styles}/prose.css (100%) rename src/{workspaces/plugins/Terminal/server => servers/api/terminal}/Dockerfile.terminal-sidecar (100%) rename src/{workspaces/plugins/Terminal/server => servers/api/terminal}/pty-sidecar.mjs (100%) rename src/{workspaces/plugins/Terminal/server => servers/api/terminal}/templates/.zshrc (100%) rename src/{workspaces/plugins/Terminal/server => servers/api/terminal}/templates/starship-officer.toml (100%) rename src/{workspaces/plugins/Terminal/server => servers/api/terminal}/websocket.ts (97%) delete mode 100644 src/workspaces/plugins/Terminal/TERMINAL_PLUGIN.md delete mode 100644 src/workspaces/plugins/Terminal/client/Screen/index.tsx delete mode 100644 src/workspaces/plugins/Terminal/client/index.ts delete mode 100644 src/workspaces/plugins/Terminal/index.ts delete mode 100644 src/workspaces/plugins/Terminal/server/index.ts delete mode 100644 src/workspaces/themes/CatppuccinLatte/client.ts delete mode 100644 src/workspaces/themes/CatppuccinLatte/index.ts delete mode 100644 src/workspaces/themes/CatppuccinLatte/prose.css delete mode 100644 src/workspaces/themes/CatppuccinLatte/variables.css delete mode 100644 src/workspaces/themes/CatppuccinMocha/client.ts delete mode 100644 src/workspaces/themes/CatppuccinMocha/index.ts delete mode 100644 src/workspaces/themes/CatppuccinMocha/prose.css delete mode 100644 src/workspaces/themes/CatppuccinMocha/variables.css delete mode 100644 src/workspaces/themes/DuckPond/client.ts delete mode 100644 src/workspaces/themes/DuckPond/index.ts delete mode 100644 src/workspaces/themes/DuckPond/variables.css delete mode 100644 src/workspaces/themes/Everforest/client.ts delete mode 100644 src/workspaces/themes/Everforest/index.ts delete mode 100644 src/workspaces/themes/Everforest/prose.css delete mode 100644 src/workspaces/themes/Everforest/variables.css delete mode 100644 src/workspaces/themes/Gruvbox/client.ts delete mode 100644 src/workspaces/themes/Gruvbox/index.ts delete mode 100644 src/workspaces/themes/Gruvbox/prose.css delete mode 100644 src/workspaces/themes/Gruvbox/variables.css delete mode 100644 src/workspaces/themes/Kanagawa/client.ts delete mode 100644 src/workspaces/themes/Kanagawa/index.ts delete mode 100644 src/workspaces/themes/Kanagawa/prose.css delete mode 100644 src/workspaces/themes/Kanagawa/variables.css delete mode 100644 src/workspaces/themes/MatteBlack/client.ts delete mode 100644 src/workspaces/themes/MatteBlack/index.ts delete mode 100644 src/workspaces/themes/MatteBlack/prose.css delete mode 100644 src/workspaces/themes/MatteBlack/variables.css delete mode 100644 src/workspaces/themes/Nord/client.ts delete mode 100644 src/workspaces/themes/Nord/index.ts delete mode 100644 src/workspaces/themes/Nord/prose.css delete mode 100644 src/workspaces/themes/Nord/variables.css delete mode 100644 src/workspaces/themes/OsakaJade/client.ts delete mode 100644 src/workspaces/themes/OsakaJade/index.ts delete mode 100644 src/workspaces/themes/OsakaJade/prose.css delete mode 100644 src/workspaces/themes/OsakaJade/variables.css delete mode 100644 src/workspaces/themes/Ristretto/client.ts delete mode 100644 src/workspaces/themes/Ristretto/index.ts delete mode 100644 src/workspaces/themes/Ristretto/prose.css delete mode 100644 src/workspaces/themes/Ristretto/variables.css delete mode 100644 src/workspaces/themes/RosePine/client.ts delete mode 100644 src/workspaces/themes/RosePine/index.ts delete mode 100644 src/workspaces/themes/RosePine/prose.css delete mode 100644 src/workspaces/themes/RosePine/variables.css delete mode 100644 src/workspaces/themes/TokyoNight/client.ts delete mode 100644 src/workspaces/themes/TokyoNight/index.ts delete mode 100644 src/workspaces/themes/TokyoNight/prose.css delete mode 100644 src/workspaces/themes/TokyoNight/variables.css delete mode 100644 src/workspaces/themes/index.ts delete mode 100644 src/workspaces/themes/package.json rename src/workspaces/{plugins/Terminal/client => widgets}/TerminalView.tsx (100%) create mode 100644 src/workspaces/widgets/package.json diff --git a/bun.lock b/bun.lock index a00cb113..064dbf6a 100644 --- a/bun.lock +++ b/bun.lock @@ -99,10 +99,10 @@ "sounds": "workspace:*", "tailwind-merge": "^3.3.1", "tailwindcss-animate": "^1.0.7", - "themes": "workspace:*", "three": "^0.182.0", "types": "workspace:*", "vaul": "^1.1.2", + "widgets": "workspace:*", "ws": "^8.18.1", "zod": "^4.2.1", }, @@ -240,13 +240,13 @@ "name": "sounds", "version": "1.0.0", }, - "src/workspaces/themes": { - "name": "themes", - }, "src/workspaces/types": { "name": "types", "version": "0.0.1", }, + "src/workspaces/widgets": { + "name": "widgets", + }, }, "packages": { "@alloc/quick-lru": ["@alloc/quick-lru@5.2.0", "", {}, "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw=="], @@ -2003,8 +2003,6 @@ "text-segmentation": ["text-segmentation@1.0.3", "", { "dependencies": { "utrie": "^1.0.2" } }, "sha512-iOiPUo/BGnZ6+54OsWxZidGCsdU8YbE4PSpdPinp7DeMtUJNJBoJ/ouUSTJjHkh1KntHaltHl/gDs2FC4i5+Nw=="], - "themes": ["themes@workspace:src/workspaces/themes"], - "thenify": ["thenify@3.3.1", "", { "dependencies": { "any-promise": "^1.0.0" } }, "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw=="], "thenify-all": ["thenify-all@1.6.0", "", { "dependencies": { "thenify": ">= 3.1.0 < 4" } }, "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA=="], @@ -2115,6 +2113,8 @@ "which": ["which@2.0.2", "", { "dependencies": { "isexe": "^2.0.0" }, "bin": { "node-which": "./bin/node-which" } }, "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA=="], + "widgets": ["widgets@workspace:src/workspaces/widgets"], + "wrap-ansi": ["wrap-ansi@8.1.0", "", { "dependencies": { "ansi-styles": "^6.1.0", "string-width": "^5.0.1", "strip-ansi": "^7.0.1" } }, "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ=="], "wrap-ansi-cjs": ["wrap-ansi@7.0.0", "", { "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" } }, "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q=="], diff --git a/package.json b/package.json index ca824df9..f31b7b11 100644 --- a/package.json +++ b/package.json @@ -99,6 +99,7 @@ "pg": "^8.16.3", "postgres": "^3.4.5", "plugins": "workspace:*", + "widgets": "workspace:*", "react": "^19", "react-countup": "^6.5.3", "react-day-picker": "^9.13.0", @@ -117,7 +118,6 @@ "sonner": "^2.0.7", "sounds": "workspace:*", "tailwind-merge": "^3.3.1", - "themes": "workspace:*", "tailwindcss-animate": "^1.0.7", "three": "^0.182.0", "types": "workspace:*", diff --git a/src/apps/officer-web/App.tsx b/src/apps/officer-web/App.tsx index f3cb7f95..fc6d94b2 100644 --- a/src/apps/officer-web/App.tsx +++ b/src/apps/officer-web/App.tsx @@ -1,9 +1,6 @@ -import { BrowserRouter, Routes, Route, Navigate, Link } from 'react-router'; +import { BrowserRouter, Routes, Route, Navigate } from 'react-router'; import * as Authentication from './Screens/Authentication'; -// import { Home } from './Screens/Dashboard/Home'; - -// import { ChatList } from './Screens/Dashboard/Chat/ChatList'; - +import * as Dashboard from './Screens/Dashboard'; import { useAuth } from 'hooks/useAuth'; import { useServerSettings } from '@/state/useServerSettings'; import { useInitialData } from '@/state/useInitialData'; @@ -36,38 +33,28 @@ export function App() { {/* */} {/* )} */} {isAuthenticated && onboardingComplete && ( - - } /> - {/* } /> */} - {/* } /> */} - {/* } /> */} - {/* } /> */} - {/* } /> */} - {/* } /> */} - {/* } /> */} - {/* } /> */} - {/* } /> */} - {/* } /> */} - {/* } /> */} - {/* } /> */} - {/* } /> */} - {/* } /> */} - {/* } /> */} - {/* } /> */} - } /> - } /> - + + + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + + )} ); } - - -const HomeScreen = () => { - return ( -
-

Home

- Signout -
- ); -}; diff --git a/src/apps/officer-web/Screens/Dashboard/Chat/ChatList/index.tsx b/src/apps/officer-web/Screens/Dashboard/Chat/ChatList/index.tsx index 598e3e1b..3cc515ed 100644 --- a/src/apps/officer-web/Screens/Dashboard/Chat/ChatList/index.tsx +++ b/src/apps/officer-web/Screens/Dashboard/Chat/ChatList/index.tsx @@ -1,11 +1,4 @@ -import { DashboardLayout } from '@/Screens/Dashboard/Layout'; - export const ChatList = () => { - - return ( - -

ChatList

-
- ); + return

ChatList

; }; diff --git a/src/apps/officer-web/Screens/Dashboard/Chat/index.tsx b/src/apps/officer-web/Screens/Dashboard/Chat/index.tsx index 73728210..f2242134 100644 --- a/src/apps/officer-web/Screens/Dashboard/Chat/index.tsx +++ b/src/apps/officer-web/Screens/Dashboard/Chat/index.tsx @@ -3,7 +3,6 @@ import { useParams } from 'react-router'; import { useQueryClient } from '@tanstack/react-query'; import { useClaude, useOpenCode, type SessionEntry } from 'plugins/Chat/client'; import { ChatPanel } from 'plugins/ChatHistory/client'; -import { DashboardLayout } from '../Layout'; import { useVisibleClaudeModels, useVisibleOpenCodeModels } from '@/state/useModels'; export const ClaudeChat = () => { @@ -15,13 +14,11 @@ export const ClaudeChat = () => { const claudeModels = useVisibleClaudeModels(); return ( - -
-
- -
+
+
+
- +
); }; @@ -34,13 +31,11 @@ export const OpenCodeChat = () => { const openCodeModels = useVisibleOpenCodeModels(); return ( - -
-
- -
+
+
+
- +
); }; @@ -69,16 +64,14 @@ export const NewChat = () => { const [provider, setProvider] = useState<'claude' | 'opencode'>('claude'); return ( - -
-
- {provider === 'claude' ? ( - - ) : ( - - )} -
+
+
+ {provider === 'claude' ? ( + + ) : ( + + )}
- +
); }; diff --git a/src/apps/officer-web/Screens/Dashboard/Home/index.tsx b/src/apps/officer-web/Screens/Dashboard/Home/index.tsx index a048457a..a3a4109b 100644 --- a/src/apps/officer-web/Screens/Dashboard/Home/index.tsx +++ b/src/apps/officer-web/Screens/Dashboard/Home/index.tsx @@ -1,25 +1,19 @@ -import { DashboardLayout } from '../Layout'; import { ChatLauncher } from './ChatLauncher'; import { Widget as FileBrowser } from 'plugins/FileBrowser/client'; import { Widget as ChatHistory } from 'plugins/ChatHistory/client'; import { Catalog } from 'sounds'; -import { useServerSettings } from '@/state/useServerSettings'; - -export const Home = () => { - const { plugins } = useServerSettings(); +export const HomeScreen = () => { return ( - -
-
- - {plugins?.FileBrowser !== false && } -
-
- - -
+
+
+ +
- +
+ + +
+
); }; diff --git a/src/apps/officer-web/Screens/Dashboard/Layout.tsx b/src/apps/officer-web/Screens/Dashboard/Layout.backup.tsx similarity index 100% rename from src/apps/officer-web/Screens/Dashboard/Layout.tsx rename to src/apps/officer-web/Screens/Dashboard/Layout.backup.tsx diff --git a/src/apps/officer-web/Screens/Dashboard/Layout/AuthenticationLayout.tsx b/src/apps/officer-web/Screens/Dashboard/Layout/AuthenticationLayout.tsx deleted file mode 100644 index cf503f6b..00000000 --- a/src/apps/officer-web/Screens/Dashboard/Layout/AuthenticationLayout.tsx +++ /dev/null @@ -1,21 +0,0 @@ -import { Background } from './Background'; -type AuthenticationLayoutProps = { - children?: React.ReactNode; -}; -export function AuthenticationLayout({ children }: AuthenticationLayoutProps) { - return ( -
-
- -
-
- {children} -
-
-
- -
- ); -}; - - diff --git a/src/apps/officer-web/Screens/Dashboard/Layout/Background.tsx b/src/apps/officer-web/Screens/Dashboard/Layout/Background.tsx index b9511e7e..07823073 100644 --- a/src/apps/officer-web/Screens/Dashboard/Layout/Background.tsx +++ b/src/apps/officer-web/Screens/Dashboard/Layout/Background.tsx @@ -1,4 +1,3 @@ -import { DuckAvatar } from "./DuckAvatar"; import { PixelGrid } from "@/components/PixelGrid"; import landscapebg from './landscape1.jpg'; @@ -13,7 +12,6 @@ export function Background() { }} > -
); }; diff --git a/src/apps/officer-web/Screens/Dashboard/Layout/DashboardLayout.tsx b/src/apps/officer-web/Screens/Dashboard/Layout/DashboardLayout.tsx new file mode 100644 index 00000000..e70d6af4 --- /dev/null +++ b/src/apps/officer-web/Screens/Dashboard/Layout/DashboardLayout.tsx @@ -0,0 +1,24 @@ +import { Background } from './Background'; +import { Header } from './Header'; +import { Dock, dockItems } from './Dock'; + +type DashboardLayoutProps = { + children?: React.ReactNode; +}; +export function DashboardLayout({ children }: DashboardLayoutProps) { + return ( +
+
+
+ + +
+ {children} +
+
+ +
+ ); +}; + + diff --git a/src/apps/officer-web/Screens/Dashboard/Dock.tsx b/src/apps/officer-web/Screens/Dashboard/Layout/Dock.tsx similarity index 75% rename from src/apps/officer-web/Screens/Dashboard/Dock.tsx rename to src/apps/officer-web/Screens/Dashboard/Layout/Dock.tsx index 83c1f3d9..66d1d0ee 100644 --- a/src/apps/officer-web/Screens/Dashboard/Dock.tsx +++ b/src/apps/officer-web/Screens/Dashboard/Layout/Dock.tsx @@ -46,7 +46,7 @@ export const Dock = ({ items, className }: DockProps) => { ref={dockRef} onMouseMove={handleMouseMove} onMouseLeave={handleMouseLeave} - className={`fixed bottom-4 left-1/2 -translate-x-1/2 z-[550] items-end gap-2 md:gap-6 px-2 py-1.5 md:px-3 md:py-2 rounded-2xl border backdrop-blur-xl shadow-lg ${className ?? 'flex'}`} + className={`fixed bottom-4 left-1/2 -translate-x-1/2 z-5 items-end gap-2 md:gap-6 px-2 py-1.5 md:px-3 md:py-2 rounded-2xl border backdrop-blur-xl shadow-lg ${className ?? 'flex'}`} style={{ backgroundColor: 'var(--dock-bg)', borderColor: 'var(--dock-border)' }} > {items.map((item, index) => { @@ -89,3 +89,18 @@ export const Dock = ({ items, className }: DockProps) => {
); }; + + +import { Terminal, TerminalSquare, FileText, FolderOpen } from 'lucide-react'; +import { Sparkles, ClipboardList, ScrollText, Workflow } from 'lucide-react'; + +export const dockItems: DockItem[] = [ + { label: 'Chat', to: '/chat', icon: Terminal, color: '#60a5fa' }, + { label: 'Files', to: '/files', icon: FolderOpen, color: '#fbbf24' }, + { label: 'Terminal', to: '/terminal', icon: TerminalSquare, color: '#34d399' }, + { label: 'Plans', to: '/plans', icon: FileText, color: '#f472b6' }, + { label: 'Skills', to: '/skills', icon: Sparkles, color: '#c084fc' }, + { label: 'Tasks', to: '/tasks', icon: ClipboardList, color: '#fb923c' }, + { label: 'Processes', to: '/processes', icon: Workflow, color: '#2dd4bf' }, + { label: 'Logs', to: '/task-logs', icon: ScrollText, color: '#94a3b8' }, +]; diff --git a/src/apps/officer-web/Screens/Dashboard/Layout/DuckAvatar/DebugPanel.tsx b/src/apps/officer-web/Screens/Dashboard/Layout/DuckAvatar/DebugPanel.tsx deleted file mode 100644 index 2430b179..00000000 --- a/src/apps/officer-web/Screens/Dashboard/Layout/DuckAvatar/DebugPanel.tsx +++ /dev/null @@ -1,43 +0,0 @@ -type DebugPanelProps = { - fullControlMode: boolean; - cameraInfo: { - cameraPosition: number[]; - target: number[]; - zoom: number; - }; - modelInfo: { - position: number[]; - rotation: number[]; - scale: number; - }; -}; - -export function DebugPanel({ fullControlMode, cameraInfo, modelInfo }: DebugPanelProps) { - return ( -
-
Controls:
-
- Mode: {fullControlMode ? 'FULL CONTROL' : 'ROTATION ONLY'} -
-
* Left-click/Touch + drag: Rotate
- {fullControlMode && ( - <> -
* Right-click + drag: Pan
-
* Scroll: Zoom
- - )} -
* Ctrl+Alt+Enter: Toggle full control
-
* Ctrl+Alt+D: Toggle debug panel
- -
Camera:
-
Position: [{cameraInfo.cameraPosition.map((v) => v.toFixed(2)).join(', ')}]
-
Target: [{cameraInfo.target.map((v) => v.toFixed(2)).join(', ')}]
-
Zoom: {cameraInfo.zoom.toFixed(2)}
- -
Model:
-
Position: [{modelInfo.position.map((v) => v.toFixed(2)).join(', ')}]
-
Rotation: [{modelInfo.rotation.map((v) => v.toFixed(2)).join(', ')}]
-
Scale: {modelInfo.scale.toFixed(2)}
-
- ); -} diff --git a/src/apps/officer-web/Screens/Dashboard/Layout/DuckAvatar/DuckAvatar.tsx b/src/apps/officer-web/Screens/Dashboard/Layout/DuckAvatar/DuckAvatar.tsx deleted file mode 100644 index f0f90e83..00000000 --- a/src/apps/officer-web/Screens/Dashboard/Layout/DuckAvatar/DuckAvatar.tsx +++ /dev/null @@ -1,118 +0,0 @@ -import { Canvas, useThree } from '@react-three/fiber'; -import { OrbitControls } from '@react-three/drei'; -import { useEffect, useState, useRef } from 'react'; -import { DuckModel } from './DuckModel'; -import { DebugPanel } from './DebugPanel'; - -type CameraInfoProps = { - onUpdate: (info: { cameraPosition: number[]; target: number[]; zoom: number }) => void; - initialTarget: [number, number, number]; - fullControlMode: boolean; - initialPosition: [number, number, number]; -}; - -function CameraInfo({ onUpdate, initialTarget, fullControlMode, initialPosition }: CameraInfoProps) { - const { camera } = useThree(); - const controlsRef = useRef(null); - - useEffect(() => { - if (controlsRef.current) { - controlsRef.current.target.set(...initialTarget); - camera.position.set(...initialPosition); - controlsRef.current.update(); - } - }, [initialTarget, initialPosition, camera]); - - useEffect(() => { - const interval = setInterval(() => { - if (controlsRef.current) { - const controls = controlsRef.current; - onUpdate({ - cameraPosition: camera.position.toArray(), - target: controls.target.toArray(), - zoom: camera.zoom, - }); - } - }, 100); - - return () => clearInterval(interval); - }, [camera, onUpdate]); - - return ( - - ); -} - -type DuckAvatarProps = { - showDebug: boolean; - fullControlMode: boolean; - currentSection: number; -}; - -export function DuckAvatar({ showDebug, fullControlMode, currentSection }: DuckAvatarProps) { - const isHeroSection = currentSection === 0; - const [cameraInfo, setCameraInfo] = useState({ - cameraPosition: [2.89, 5.24, 7.38], - target: [0.3, 3.29, -0.4], - zoom: 1, - }); - - const [modelInfo, setModelInfo] = useState({ - position: [0, -0.2, 0], - rotation: [-0.1, -0.75, 0], - scale: 4.5, - }); - - const [isLoaded, setIsLoaded] = useState(false); - - const heroClasses = 'fixed top-12 md:top-auto md:bottom-0 left-1/2 -translate-x-1/2 w-[60vh] h-[75vh]'; - const miniClasses = 'fixed bottom-4 right-4 w-[20vh] h-[25vh]'; - - return ( -
-
- - - - - - - { - setIsLoaded(true); - }} - currentSection={currentSection} - /> - -
- {showDebug && } -
- ); -} diff --git a/src/apps/officer-web/Screens/Dashboard/Layout/DuckAvatar/DuckModel.tsx b/src/apps/officer-web/Screens/Dashboard/Layout/DuckAvatar/DuckModel.tsx deleted file mode 100644 index 98062a63..00000000 --- a/src/apps/officer-web/Screens/Dashboard/Layout/DuckAvatar/DuckModel.tsx +++ /dev/null @@ -1,68 +0,0 @@ -import { useRef, useEffect } from 'react'; -import { useGLTF, useAnimations } from '@react-three/drei'; - -type DuckModelProps = { - onUpdate: (info: { position: number[]; rotation: number[]; scale: number }) => void; - onAssetsLoaded: () => void; - currentSection: number; -}; - -export function DuckModel({ onUpdate, onAssetsLoaded, currentSection }: DuckModelProps) { - const character = useGLTF('/static/duck3D/Character_output.glb'); - const animations = useGLTF('/static/duck3D/Meshy_Merged_Animations.glb'); - const meshRef = useRef(null); - const { actions } = useAnimations(animations.animations, meshRef); - - useEffect(() => { - onAssetsLoaded(); - }, [character, animations, onAssetsLoaded]); - - useEffect(() => { - if (!actions) return; - - const isContactSection = currentSection === 6; - - if (isContactSection) { - Object.values(actions).forEach((a) => a?.fadeOut(0.4)); - return; - } - - const action = actions['Walking']; - if (!action) return; - - Object.values(actions).forEach((a) => a?.fadeOut(0.4)); - - action.reset(); - action.setLoop(2201, Infinity); - action.clampWhenFinished = false; - action.fadeIn(0.4); - action.play(); - }, [actions, currentSection]); - - useEffect(() => { - const interval = setInterval(() => { - if (meshRef.current) { - onUpdate({ - position: meshRef.current.position.toArray(), - rotation: meshRef.current.rotation.toArray().slice(0, 3), - scale: meshRef.current.scale.x, - }); - } - }, 100); - - return () => clearInterval(interval); - }, [onUpdate]); - - const isContactSection = currentSection === 6; - const rotationY = isContactSection ? 0 : (10 * Math.PI) / 180; - - return ( - - ); -} diff --git a/src/apps/officer-web/Screens/Dashboard/Layout/DuckAvatar/index.tsx b/src/apps/officer-web/Screens/Dashboard/Layout/DuckAvatar/index.tsx deleted file mode 100644 index 01fcd376..00000000 --- a/src/apps/officer-web/Screens/Dashboard/Layout/DuckAvatar/index.tsx +++ /dev/null @@ -1 +0,0 @@ -export * from './DuckAvatar'; diff --git a/src/apps/officer-web/Screens/Dashboard/Layout/Header/Header.tsx b/src/apps/officer-web/Screens/Dashboard/Layout/Header/Header.tsx new file mode 100644 index 00000000..71e4369b --- /dev/null +++ b/src/apps/officer-web/Screens/Dashboard/Layout/Header/Header.tsx @@ -0,0 +1,25 @@ +import { Link } from 'react-router'; +import { UserMenu } from './UserMenu'; + +export function Header() { + return ( +
+
+ + Officer + + + +
+
+ ); +} + diff --git a/src/apps/officer-web/Screens/Dashboard/Layout/Header/UserMenu.tsx b/src/apps/officer-web/Screens/Dashboard/Layout/Header/UserMenu.tsx new file mode 100644 index 00000000..1892f559 --- /dev/null +++ b/src/apps/officer-web/Screens/Dashboard/Layout/Header/UserMenu.tsx @@ -0,0 +1,59 @@ +import { Link } from 'react-router'; +import * as Dropdown from '@/components/ui/dropdown-menu'; +import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar'; +import { User, LogOut, Server, Package, Bot } from 'lucide-react'; +import { useAuth } from 'hooks/useAuth'; + +const { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } = Dropdown; + +export function UserMenu() { + const { user, isLoading } = useAuth(); + if (isLoading) return null; + + return ( + + + + + + + + + Profile + + + + + + AI Settings + + + + + + Server Settings + + + + + + Resources + + + + + + Sign Out + + + + + ); +}; diff --git a/src/apps/officer-web/Screens/Dashboard/Layout/Header/index.tsx b/src/apps/officer-web/Screens/Dashboard/Layout/Header/index.tsx new file mode 100644 index 00000000..266dec8a --- /dev/null +++ b/src/apps/officer-web/Screens/Dashboard/Layout/Header/index.tsx @@ -0,0 +1 @@ +export * from './Header'; diff --git a/src/apps/officer-web/Screens/Dashboard/Layout/index.tsx b/src/apps/officer-web/Screens/Dashboard/Layout/index.tsx index f3db7e1c..fc36c152 100644 --- a/src/apps/officer-web/Screens/Dashboard/Layout/index.tsx +++ b/src/apps/officer-web/Screens/Dashboard/Layout/index.tsx @@ -1 +1 @@ -export * from './AuthenticationLayout'; +export * from './DashboardLayout'; diff --git a/src/apps/officer-web/Screens/Dashboard/OnboardingAdmin/index.tsx b/src/apps/officer-web/Screens/Dashboard/OnboardingAdmin/index.tsx index 4bc8c441..bd3e7781 100644 --- a/src/apps/officer-web/Screens/Dashboard/OnboardingAdmin/index.tsx +++ b/src/apps/officer-web/Screens/Dashboard/OnboardingAdmin/index.tsx @@ -1,6 +1,5 @@ import { useState, useEffect } from 'react'; import { useServerSettings } from '@/state/useServerSettings'; -import { DashboardLayout } from '../Layout'; import { ServerTypeCard } from './ServerTypeCard'; import { AIHarnessesCard } from './AIHarnessesCard'; @@ -46,15 +45,13 @@ export const OnboardingAdmin = () => { }; return ( - -
-
- {step === 'server-type' && } - {step === 'ai-harnesses' && ( - - )} -
+
+
+ {step === 'server-type' && } + {step === 'ai-harnesses' && ( + + )}
- +
); }; diff --git a/src/apps/officer-web/Screens/Dashboard/Plans/index.tsx b/src/apps/officer-web/Screens/Dashboard/Plans/index.tsx index 8192c43b..cd06f473 100644 --- a/src/apps/officer-web/Screens/Dashboard/Plans/index.tsx +++ b/src/apps/officer-web/Screens/Dashboard/Plans/index.tsx @@ -5,8 +5,6 @@ import remarkGfm from 'remark-gfm'; import rehypeRaw from 'rehype-raw'; import { useClient } from 'hooks/useClient'; import { Card } from '@/components/Card'; -import { DashboardLayout } from '../Layout'; - export const Plans = () => { const client = useClient(); const [selectedPlan, setSelectedPlan] = useState(null); @@ -29,8 +27,7 @@ export const Plans = () => { }); return ( - -
+
{/* Header with plan selector */}
@@ -59,7 +56,6 @@ export const Plans = () => {
-
-
+
); }; diff --git a/src/apps/officer-web/Screens/Dashboard/ResourcePage.tsx b/src/apps/officer-web/Screens/Dashboard/ResourcePage.tsx index fa4ad370..a2e1aa58 100644 --- a/src/apps/officer-web/Screens/Dashboard/ResourcePage.tsx +++ b/src/apps/officer-web/Screens/Dashboard/ResourcePage.tsx @@ -11,8 +11,6 @@ import { useClient } from 'hooks/useClient'; import { useVisibleClaudeModels } from '@/state/useModels'; import { Card } from '@/components/Card'; import { useClaude, EmbeddableChat, type ChatMessage } from 'plugins/Chat/client'; -import { DashboardLayout } from './Layout'; - type ResourceSummary = { dirName: string; name: string; @@ -180,7 +178,7 @@ export const ResourcePage = ({ kind, endpoint, queryKey }: ResourcePageProps) => ); return ( - + <>
{/* Left panel — list */}
-
+ ); }; diff --git a/src/apps/officer-web/Screens/Dashboard/Settings/AISettings.tsx b/src/apps/officer-web/Screens/Dashboard/Settings/AISettings.tsx index 8a0a50a0..370c2e5b 100644 --- a/src/apps/officer-web/Screens/Dashboard/Settings/AISettings.tsx +++ b/src/apps/officer-web/Screens/Dashboard/Settings/AISettings.tsx @@ -11,7 +11,6 @@ import { Tabs, TabsList, TabsTrigger, TabsContent } from '@/components/ui/tabs'; import { Accordion, AccordionItem, AccordionTrigger, AccordionContent } from '@/components/ui/accordion'; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'; import { Card } from '@/components/Card'; -import { DashboardLayout } from '../Layout'; import { useSettings } from '@/state/useSettings'; import { useUserState } from '@/state/useUserState'; import { @@ -26,9 +25,8 @@ export const AISettings = () => { const [mainTab, setMainTab] = useUserState('ai-settings-tab', 'chat-defaults'); return ( - -
- +
+ @@ -49,9 +47,8 @@ export const AISettings = () => { - -
- +
+
); }; diff --git a/src/apps/officer-web/Screens/Dashboard/Settings/ProfileSettings/index.tsx b/src/apps/officer-web/Screens/Dashboard/Settings/ProfileSettings/index.tsx index eaacaaf0..1739cd43 100644 --- a/src/apps/officer-web/Screens/Dashboard/Settings/ProfileSettings/index.tsx +++ b/src/apps/officer-web/Screens/Dashboard/Settings/ProfileSettings/index.tsx @@ -3,12 +3,10 @@ import { Search, User, Lock, Globe, ListChecks, Palette } from 'lucide-react'; import { Input } from '@/components/ui/input'; import { Accordion, AccordionItem, AccordionTrigger, AccordionContent } from '@/components/ui/accordion'; import { Card } from '@/components/Card'; -import { DashboardLayout } from '../../Layout'; import { UserData } from './UserData'; import { ChangePassword } from './ChangePassword'; import { Languages } from './Languages'; import { TaskDefaults } from './TaskDefaults'; -import { Appearance } from './Appearance'; const sections = [ { @@ -19,11 +17,11 @@ const sections = [ content: , }, { - key: 'appearance', - icon: Palette, - title: 'Appearance', - description: 'Color theme and light/dark mode.', - content: , + key: 'change-password', + icon: Lock, + title: 'Change Password', + description: 'Update your account password.', + content: , }, { key: 'tasks', @@ -39,13 +37,6 @@ const sections = [ description: 'Set your spoken languages and translation preferences.', content: , }, - { - key: 'change-password', - icon: Lock, - title: 'Change Password', - description: 'Update your account password.', - content: , - }, ]; const allKeys = sections.map((s) => s.key); @@ -71,42 +62,40 @@ export const ProfileSettings = () => { }, [search, matchingKeys]); return ( - -
- -
- - setSearch(ev.target.value)} - className="pl-9" - /> -
+
+ +
+ + setSearch(ev.target.value)} + className="pl-9" + /> +
- - {sections.map((section) => ( -
{ - sectionRefs.current[section.key] = el; - }} - className={search && !matchingKeys.includes(section.key) ? 'hidden' : ''} - > - - -
- -
{section.title}
-
-
- {section.content} -
-
- ))} -
-
-
- + + {sections.map((section) => ( +
{ + sectionRefs.current[section.key] = el; + }} + className={search && !matchingKeys.includes(section.key) ? 'hidden' : ''} + > + + +
+ +
{section.title}
+
+
+ {section.content} +
+
+ ))} +
+
+
); }; diff --git a/src/apps/officer-web/Screens/Dashboard/Settings/ResourceSettings/index.tsx b/src/apps/officer-web/Screens/Dashboard/Settings/ResourceSettings/index.tsx index c9a99de9..990f7b17 100644 --- a/src/apps/officer-web/Screens/Dashboard/Settings/ResourceSettings/index.tsx +++ b/src/apps/officer-web/Screens/Dashboard/Settings/ResourceSettings/index.tsx @@ -5,7 +5,6 @@ import { toast } from 'sonner'; import { Button } from '@/components/ui/button'; import { Card } from '@/components/Card'; import { useClient } from 'hooks/useClient'; -import { DashboardLayout } from '../../Layout'; import { EmbeddableChat, useClaude, useOpenCode } from 'plugins/Chat/client'; import { useVisibleClaudeModels, useVisibleOpenCodeModels } from '@/state/useModels'; @@ -82,8 +81,7 @@ export const ResourceSettings = () => { const [provider, setProvider] = useState<'claude' | 'opencode'>('claude'); return ( - -
+

Applications

System tools and dependencies used by Officer.dev

@@ -175,8 +173,7 @@ export const ResourceSettings = () => { )}
-
- +
); }; diff --git a/src/apps/officer-web/Screens/Dashboard/Settings/ServerSettings/index.tsx b/src/apps/officer-web/Screens/Dashboard/Settings/ServerSettings/index.tsx index 51aca995..3cb79fd3 100644 --- a/src/apps/officer-web/Screens/Dashboard/Settings/ServerSettings/index.tsx +++ b/src/apps/officer-web/Screens/Dashboard/Settings/ServerSettings/index.tsx @@ -1,11 +1,10 @@ import { useState, useEffect, useRef, useMemo } from 'react'; -import { Search, Terminal, Puzzle, Shield } from 'lucide-react'; +import { Search, Terminal, Shield } from 'lucide-react'; import { Input } from '@/components/ui/input'; import { Accordion, AccordionItem, AccordionTrigger, AccordionContent } from '@/components/ui/accordion'; import { Card } from '@/components/Card'; -import { DashboardLayout } from '../../Layout'; import { AIHarnessesSection } from './AIHarnessesSection'; -import { PluginsSection } from './PluginsSection'; +// import { PluginsSection } from './PluginsSection'; import { TerminalSection } from './TerminalSection'; const sections = [ @@ -16,13 +15,13 @@ const sections = [ description: 'Which AI coding tools do you use?', content: , }, - { - key: 'plugins', - icon: Puzzle, - title: 'Plugins', - description: 'Enable or disable installed plugins.', - content: , - }, + // { + // key: 'plugins', + // icon: Puzzle, + // title: 'Plugins', + // description: 'Enable or disable installed plugins.', + // content: , + // }, { key: 'terminal', icon: Shield, @@ -55,45 +54,43 @@ export const ServerSettings = () => { }, [search, matchingKeys]); return ( - -
- -
- - setSearch(ev.target.value)} - className="pl-9" - /> -
+
+ +
+ + setSearch(ev.target.value)} + className="pl-9" + /> +
- - {sections.map((section) => ( -
{ - sectionRefs.current[section.key] = el; - }} - className={search && !matchingKeys.includes(section.key) ? 'hidden' : ''} - > - - -
- -
-
{section.title}
-
{section.description}
-
+ + {sections.map((section) => ( +
{ + sectionRefs.current[section.key] = el; + }} + className={search && !matchingKeys.includes(section.key) ? 'hidden' : ''} + > + + +
+ +
+
{section.title}
+
{section.description}
- - {section.content} - -
- ))} - - -
- +
+
+ {section.content} +
+
+ ))} +
+
+
); }; diff --git a/src/apps/officer-web/Screens/Dashboard/Settings/index.tsx b/src/apps/officer-web/Screens/Dashboard/Settings/index.tsx index 2ed14cd2..3261e197 100644 --- a/src/apps/officer-web/Screens/Dashboard/Settings/index.tsx +++ b/src/apps/officer-web/Screens/Dashboard/Settings/index.tsx @@ -1,29 +1,4 @@ -import { Link } from 'react-router'; -import { Bot, ChevronRight } from 'lucide-react'; -import { Card } from '@/components/Card'; -import { DashboardLayout } from '../Layout'; - -export const Settings = () => { - return ( - -
-
- - -
-
- -
-

AI Settings

-

Chat defaults, model visibility

-
-
- -
-
- -
-
-
- ); -}; +export * from './ProfileSettings'; +export * from './AISettings'; +export * from './ServerSettings'; +export * from './ResourceSettings'; diff --git a/src/apps/officer-web/Screens/Dashboard/TaskLogs/index.tsx b/src/apps/officer-web/Screens/Dashboard/TaskLogs/index.tsx index ec2bf640..285e2f70 100644 --- a/src/apps/officer-web/Screens/Dashboard/TaskLogs/index.tsx +++ b/src/apps/officer-web/Screens/Dashboard/TaskLogs/index.tsx @@ -1,7 +1,6 @@ import { useState, useEffect } from 'react'; import { Search, AlertCircle, CheckCircle2, Clock, ArrowLeft } from 'lucide-react'; import { useClient } from 'hooks/useClient'; -import { DashboardLayout } from '../Layout'; import { Card } from '@/components/Card'; import { MessageBubble, type ChatMessage } from 'plugins/Chat/client'; @@ -77,8 +76,7 @@ export const TaskLogs = () => { : logs; return ( - -
+
{/* Left panel: list */} { )} -
- +
); }; diff --git a/src/apps/officer-web/Screens/Dashboard/Terminal/index.tsx b/src/apps/officer-web/Screens/Dashboard/Terminal/index.tsx new file mode 100644 index 00000000..b5e7f15d --- /dev/null +++ b/src/apps/officer-web/Screens/Dashboard/Terminal/index.tsx @@ -0,0 +1,5 @@ +import { TerminalView } from 'widgets/TerminalView'; + +export const Terminal = () => { + return ; +}; diff --git a/src/apps/officer-web/Screens/Dashboard/index.tsx b/src/apps/officer-web/Screens/Dashboard/index.tsx new file mode 100644 index 00000000..6af169fd --- /dev/null +++ b/src/apps/officer-web/Screens/Dashboard/index.tsx @@ -0,0 +1,13 @@ +export * from './Layout'; +export * from './Home'; +export * from './Chat'; +export * from './OnboardingAdmin'; +export * from './PasskeyGate'; +export * from './Plans'; +export * from './Processes'; +export * from './ResourcePage'; +export * from './Settings'; +export * from './Skills'; +export * from './TaskLogs'; +export * from './Tasks'; +export * from './Terminal'; diff --git a/src/apps/officer-web/frontend.tsx b/src/apps/officer-web/frontend.tsx index bdfa1a22..56e0db75 100644 --- a/src/apps/officer-web/frontend.tsx +++ b/src/apps/officer-web/frontend.tsx @@ -6,18 +6,6 @@ import { ThemeProvider } from '@/components/ui/ThemeProvider'; import { Toaster } from '@/components/ui/toaster'; import { Toaster as Sonner } from 'sonner'; import { TooltipProvider } from '@/components/ui/tooltip'; -import 'themes/DuckPond/client'; -import 'themes/TokyoNight/client'; -import 'themes/CatppuccinLatte/client'; -import 'themes/CatppuccinMocha/client'; -import 'themes/Everforest/client'; -import 'themes/Gruvbox/client'; -import 'themes/Kanagawa/client'; -import 'themes/MatteBlack/client'; -import 'themes/Nord/client'; -import 'themes/OsakaJade/client'; -import 'themes/Ristretto/client'; -import 'themes/RosePine/client'; import './styles/index.css'; const headLinks = [ diff --git a/src/apps/officer-web/state/useThemeSync.ts b/src/apps/officer-web/state/useThemeSync.ts index 177d2a9c..3a70b5e2 100644 --- a/src/apps/officer-web/state/useThemeSync.ts +++ b/src/apps/officer-web/state/useThemeSync.ts @@ -2,47 +2,12 @@ import { useEffect } from 'react'; import { useTheme } from '@/components/ui/ThemeProvider'; import { useSettings } from './useSettings'; -const THEME_MODES: Record = { - DuckPond: 'light', - TokyoNight: 'dark', - CatppuccinLatte: 'light', - CatppuccinMocha: 'dark', - Everforest: 'dark', - Gruvbox: 'dark', - Kanagawa: 'dark', - MatteBlack: 'dark', - Nord: 'dark', - OsakaJade: 'dark', - Ristretto: 'dark', - RosePine: 'dark', -}; - -const BG_IMAGES: Record = { - DuckPond: 'url(/static/landscape1.jpg)', -}; - export const useThemeSync = () => { const { settings } = useSettings(); const { setTheme } = useTheme(); useEffect(() => { if (!settings) return; - const colorTheme = settings.appearance.colorTheme ?? 'DuckPond'; - const root = document.documentElement; - - // Set data attribute for CSS scoping (DuckPond uses :root as default) - if (colorTheme === 'DuckPond') { - root.removeAttribute('data-color-theme'); - } else { - root.setAttribute('data-color-theme', colorTheme); - } - - // Set light/dark class based on theme mode - const mode = THEME_MODES[colorTheme] ?? 'light'; - setTheme(mode); - - // Set background image - const bgImage = BG_IMAGES[colorTheme] ?? 'none'; - root.style.setProperty('--page-bg-image', bgImage); + setTheme('light'); }, [settings?.appearance?.colorTheme]); }; diff --git a/src/apps/officer-web/styles/globals.css b/src/apps/officer-web/styles/globals.css index 85fac418..038d8bc1 100644 --- a/src/apps/officer-web/styles/globals.css +++ b/src/apps/officer-web/styles/globals.css @@ -121,6 +121,169 @@ } @layer base { + :root { + /* Duck brand hex colors */ + --duck-yellow: #F4C430; + --duck-orange: #EA580C; + --duck-teal: #0891B2; + --duck-forest: #166534; + --duck-dark: #14532D; + --duck-beige: #E7D4B5; + + /* Page background */ + --pixel-grid-color: rgba(20, 83, 45, 0.1); + + /* Glass surfaces */ + --glass-bg: rgba(255, 255, 255, 0.1); + --glass-border: rgba(255, 255, 255, 0.2); + --dock-bg: rgba(0, 0, 0, 0.15); + --dock-border: rgba(255, 255, 255, 0.1); + --dock-tooltip-bg: rgba(0, 0, 0, 0.75); + + /* Card component */ + --card-bg: rgba(255, 255, 255, 0.9); + --card-grid-color: rgba(20, 83, 45, 0.08); + + --cta: 211 74.77% 45.58%; + --cta-foreground: 0 0% 100%; + + --naturegreen: 145 79% 38%; + --naturegreen-foreground: 0 0% 100%; + + --background: 0 0% 100%; + --foreground: 222.2 84% 4.9%; + + --card: 0 0% 100%; + --card-foreground: 222.2 84% 4.9%; + + --popover: 0 0% 100%; + --popover-foreground: 222.2 84% 4.9%; + + --primary: 222.2 47.4% 11.2%; + --primary-foreground: 210 40% 98%; + + --secondary: 210 40% 96.1%; + --secondary-foreground: 222.2 47.4% 11.2%; + + --muted: 210 40% 96.1%; + --muted-foreground: 215.4 16.3% 46.9%; + + --accent: 211 74.77% 45.58%; + --accent-foreground: 0 0% 0%; + + --destructive: 0 84.2% 60.2%; + --destructive-foreground: 210 40% 98%; + + --success: 142.1 76.2% 36.3%; + --success-foreground: 355.7 100% 97.3%; + + --brand: 145 79% 38%; + --brand-foreground: 0 0% 100%; + --brand-muted: 145 40% 90%; + + --warning: 43 96% 56%; + --warning-foreground: 0 0% 0%; + + --border: 214.3 31.8% 91.4%; + --input: 214.3 31.8% 91.4%; + --ring: 222.2 84% 4.9%; + + --radius: 0.5rem; + + /* Chart gradients */ + --chart-primary: 211 82% 64%; + --chart-secondary: 211 82% 84%; + + /* Status colors */ + --status-success: 142 76% 36%; + --status-warning: 43 96% 56%; + --status-in-progress: 211 82% 64%; + + --sidebar-background: 0 0% 98%; + --sidebar-foreground: 240 5.3% 26.1%; + --sidebar-primary: 240 5.9% 10%; + --sidebar-primary-foreground: 0 0% 98%; + --sidebar-accent: 240 4.8% 95.9%; + --sidebar-accent-foreground: 240 5.9% 10%; + --sidebar-border: 220 13% 91%; + --sidebar-ring: 217.2 91.2% 59.8%; + + /* Hover Effect */ + --ctahover: 211 91.53% 34.82%; + } + + .dark { + /* Page background */ + --pixel-grid-color: rgba(200, 230, 210, 0.08); + + /* Glass surfaces */ + --glass-bg: rgba(0, 0, 0, 0.2); + --glass-border: rgba(255, 255, 255, 0.1); + --dock-bg: rgba(0, 0, 0, 0.3); + --dock-border: rgba(255, 255, 255, 0.08); + --dock-tooltip-bg: rgba(0, 0, 0, 0.85); + + /* Card component */ + --card-bg: rgba(10, 20, 15, 0.9); + --card-grid-color: rgba(200, 230, 210, 0.06); + + --background: 222.2 84% 4.9%; + --foreground: 210 40% 98%; + + --card: 222.2 84% 4.9%; + --card-foreground: 210 40% 98%; + + --popover: 222.2 84% 4.9%; + --popover-foreground: 210 40% 98%; + + --primary: 210 40% 98%; + --primary-foreground: 222.2 47.4% 11.2%; + + --secondary: 217.2 32.6% 17.5%; + --secondary-foreground: 210 40% 98%; + + --muted: 217.2 32.6% 17.5%; + --muted-foreground: 215 20.2% 65.1%; + + --accent: 211 82% 64%; + --accent-foreground: 0 0% 0%; + + --destructive: 0 62.8% 30.6%; + --destructive-foreground: 210 40% 98%; + + --success: 142.1 76.2% 36.3%; + --success-foreground: 355.7 100% 97.3%; + + --brand: 145 60% 45%; + --brand-foreground: 0 0% 100%; + --brand-muted: 145 30% 25%; + + --warning: 43 96% 56%; + --warning-foreground: 0 0% 0%; + + --border: 217.2 32.6% 17.5%; + --input: 217.2 32.6% 17.5%; + --ring: 212.7 26.8% 83.9%; + + /* Chart gradients */ + --chart-primary: 211 82% 64%; + --chart-secondary: 211 82% 84%; + + /* Status colors */ + --status-success: 142 76% 36%; + --status-warning: 43 96% 56%; + --status-in-progress: 211 82% 64%; + + --sidebar-background: 240 5.9% 10%; + --sidebar-foreground: 240 4.8% 95.9%; + --sidebar-primary: 224.3 76.3% 48%; + --sidebar-primary-foreground: 0 0% 100%; + --sidebar-accent: 240 3.7% 15.9%; + --sidebar-accent-foreground: 240 4.8% 95.9%; + --sidebar-border: 240 3.7% 15.9%; + --sidebar-ring: 217.2 91.2% 59.8%; + } + * { @apply border-border; } diff --git a/src/apps/officer-web/styles/index.css b/src/apps/officer-web/styles/index.css index 091ff2c6..208237fa 100644 --- a/src/apps/officer-web/styles/index.css +++ b/src/apps/officer-web/styles/index.css @@ -1 +1,2 @@ @import "./globals.css"; +@import "./prose.css"; diff --git a/src/workspaces/themes/DuckPond/prose.css b/src/apps/officer-web/styles/prose.css similarity index 100% rename from src/workspaces/themes/DuckPond/prose.css rename to src/apps/officer-web/styles/prose.css diff --git a/src/server.tsx b/src/server.tsx index 5a8b9c62..eb01da61 100644 --- a/src/server.tsx +++ b/src/server.tsx @@ -7,7 +7,7 @@ import { verify } from './servers/jwt'; import { officerdb, TokenBlacklist } from 'officerdb'; import { claudeWebsocket } from './servers/api/claude/websocket'; import { opencodeWebsocket } from './servers/api/opencode/websocket'; -import { terminalWebsocket } from 'plugins/Terminal/server'; +import { terminalWebsocket } from './servers/api/terminal/websocket'; import officerWeb from './apps/officer-web/index.html'; const { PORT = '5000' } = process.env; diff --git a/src/workspaces/plugins/Terminal/server/Dockerfile.terminal-sidecar b/src/servers/api/terminal/Dockerfile.terminal-sidecar similarity index 100% rename from src/workspaces/plugins/Terminal/server/Dockerfile.terminal-sidecar rename to src/servers/api/terminal/Dockerfile.terminal-sidecar diff --git a/src/workspaces/plugins/Terminal/server/pty-sidecar.mjs b/src/servers/api/terminal/pty-sidecar.mjs similarity index 100% rename from src/workspaces/plugins/Terminal/server/pty-sidecar.mjs rename to src/servers/api/terminal/pty-sidecar.mjs diff --git a/src/workspaces/plugins/Terminal/server/templates/.zshrc b/src/servers/api/terminal/templates/.zshrc similarity index 100% rename from src/workspaces/plugins/Terminal/server/templates/.zshrc rename to src/servers/api/terminal/templates/.zshrc diff --git a/src/workspaces/plugins/Terminal/server/templates/starship-officer.toml b/src/servers/api/terminal/templates/starship-officer.toml similarity index 100% rename from src/workspaces/plugins/Terminal/server/templates/starship-officer.toml rename to src/servers/api/terminal/templates/starship-officer.toml diff --git a/src/workspaces/plugins/Terminal/server/websocket.ts b/src/servers/api/terminal/websocket.ts similarity index 97% rename from src/workspaces/plugins/Terminal/server/websocket.ts rename to src/servers/api/terminal/websocket.ts index 30feb985..c8fbe060 100644 --- a/src/workspaces/plugins/Terminal/server/websocket.ts +++ b/src/servers/api/terminal/websocket.ts @@ -171,6 +171,11 @@ const startDockerSidecar = (port: number, homeDir: string, userId: number): { do const dockerId = `officer-terminal-${userId}`; const tag = 'officer-terminal-sidecar:v1'; + // Remove stale container with same name if it exists + if (dockerContainerExists(dockerId)) { + Bun.spawnSync({ cmd: [dockerPath, 'rm', '-f', dockerId], stdout: 'ignore', stderr: 'ignore' }); + } + let userArgs: string[] = []; try { const stats = statSync(homeDir); @@ -268,6 +273,7 @@ const ensureDockerContainer = async (email: string, userId: number, homeDir: str if (existing && dockerContainerExists(existing.dockerId)) { if (dockerStart(existing.dockerId)) return existing; + stopDockerSidecar(existing.dockerId); } const port = existing?.port ?? getAvailablePort(map, userId); diff --git a/src/workspaces/plugins/Terminal/TERMINAL_PLUGIN.md b/src/workspaces/plugins/Terminal/TERMINAL_PLUGIN.md deleted file mode 100644 index b93db9f6..00000000 --- a/src/workspaces/plugins/Terminal/TERMINAL_PLUGIN.md +++ /dev/null @@ -1,308 +0,0 @@ -# Terminal Plugin Spec - -This document describes the Terminal plugin implementation, architecture, and integration points. It is a reference for continuing work later. - -## Goals - -- Provide a browser terminal (xterm.js) inside Officer. -- Support two execution modes: - - Host mode: shell runs on the host machine. - - Sandbox mode: shell runs inside a Docker sidecar container. -- Keep host mode working and optional; sandbox is enabled via admin settings. -- Keep all terminal logic self-contained in the plugin. -- Allow the terminal UI to be rendered anywhere with a reusable component. - -## File Layout - -- `src/workspaces/plugins/Terminal/index.ts` - - Exports plugin metadata, client screen, and server websocket handler. -- `src/workspaces/plugins/Terminal/client/TerminalView.tsx` - - Reusable terminal component (xterm + websocket bridge). -- `src/workspaces/plugins/Terminal/client/Screen/index.tsx` - - Page wrapper that renders `TerminalView` inside `DashboardLayout`. -- `src/workspaces/plugins/Terminal/client/index.ts` - - Exports `Screen` and `TerminalView`. -- `src/workspaces/plugins/Terminal/server/websocket.ts` - - WebSocket handler for terminal sessions and sidecar orchestration. -- `src/workspaces/plugins/Terminal/server/pty-sidecar.mjs` - - Node sidecar process that owns `node-pty` and shell spawn. -- `src/workspaces/plugins/Terminal/server/Dockerfile.terminal-sidecar` - - Docker image for sandbox mode. -- `src/workspaces/plugins/Terminal/server/templates/.zshrc` -- `src/workspaces/plugins/Terminal/server/templates/starship-officer.toml` - - Template configs copied into user home for stable shell UX. - -## Client Architecture - -### TerminalView - -`TerminalView` is the reusable component that can be rendered anywhere. - -Props: - -- `className?: string` -- `style?: CSSProperties` -- `wsPath?: string` (default: `/api/terminal/ws`) -- `fontSize?: number` (default: 14) -- `fontFamily?: string` -- `theme?: { background?; foreground?; cursor?; selectionBackground? }` -- `autoFocus?: boolean` (default: true) -- `onReady?: (term: XTerm) => void` -- `onExit?: () => void` -- `onDisconnect?: () => void` - -Behavior: - -- Initializes xterm after mount for StrictMode compatibility. -- Connects to websocket at `wsPath`, appending `token` from localStorage. -- Sends `resize` on open, and on ResizeObserver changes. -- Forwards terminal input as `{ type: 'input', data }` JSON. -- Writes server output on `{ type: 'output', data }`. -- Emits `onExit` when `{ type: 'exit' }` is received. -- Emits `onDisconnect` when the websocket closes. - -### Screen - -`Screen` is a thin wrapper around `TerminalView` for the full-page route: - -``` - - - -``` - -This matches plugin conventions used by FileBrowser. - -## Server Architecture - -### WebSocket Flow - -The terminal websocket is mounted in `src/server.tsx`: - -- Path: `/api/terminal/ws` -- Auth: `token` query parameter, validated with `verify()`. -- Server handler: `terminalWebsocket` from `plugins/Terminal/server`. - -Message formats between client and server: - -- Client -> server: - - `{ type: 'input', data: string }` - - `{ type: 'resize', cols: number, rows: number }` -- Server -> client: - - `{ type: 'output', data: string }` - - `{ type: 'exit' }` - -### Sidecar Model - -The Bun server does not spawn PTYs directly. Instead it proxies to a Node sidecar -that runs `node-pty` for reliability. - -There are two sidecar modes: - -1. Host mode - - Spawns a local Node sidecar on the host via Bun. - - Sidecar binds to `127.0.0.1`. - -2. Docker sandbox mode - - Runs a Docker container per user. - - Container binds to `0.0.0.0` and is mapped to a host port. - - Container runs the same Node sidecar and shell inside the container. - -### Mode Selection - -- Settings are stored in `~/.config/officer.dev/server-settings.json`. -- `terminalSandboxed: true` enables Docker mode. -- If `terminalSandboxed` is falsy, host mode is used. - -### Sidecar Handshake - -On websocket open: - -- Determine user home: `getHomeDir(email)`. -- Ensure the home directory exists. -- Determine mode (host or docker). -- Connect to sidecar on a port (host: default 5337; docker: user-specific). -- Send init payload to sidecar: - -``` -{ - type: 'init', - shell: { command, args, name }, - cwd, - homeDir, - userLabel -} -``` - -- `userLabel` is the email used by the prompt template. -- `cwd` and `homeDir` are `/home/officer` in Docker, or the user home on host. - -### Docker Container Lifecycle - -Containers are named `officer-terminal-${userId}` and stored per user in: - -`data/terminal-containers.json` - -Rules: - -- Reuse an existing container if it exists and is running. -- Restart the container if it exists but stopped. -- Start a new container if none exists; allocate a port starting at 54000. -- Containers are left running for reuse when websocket closes. - -### Docker Image - -- Tag: `officer-terminal-sidecar:v1` -- Built from `Dockerfile.terminal-sidecar` when missing. - -Includes: - -- zsh, git, curl, ca-certificates -- oh-my-zsh -- starship -- fortune-mod, cowsay -- eza -- node, ws, node-pty - -### Shell Configuration - -Templates are copied into the user's home if missing: - -- `.zshrc` -- `.config/starship-officer.toml` - -This provides a stable base for all users while allowing per-user customization. - -Prompt requirement: - -- Format: `email@domain:officer.dev` -- Email colored in button blue (#0891B2) - -## Plugin Conventions - -- `index.ts` exports `plugin` metadata with `id` matching folder name. -- Client exports use `Widget`/`Screen` conventions. Terminal only exports `Screen` - and `TerminalView` (no widget). -- Server exports a websocket handler (not a router). This is a special-case - plugin that is mounted in `src/server.tsx`. - -## Known Constraints - -- Terminal mode is global via server settings; no per-component mode selection. -- `TerminalView` builds the websocket URL from `window.location` and localStorage - token; custom auth is not supported yet. -- Sidecar connection retries are bounded; errors are printed to the terminal. - -## Potential Future Enhancements - -- Allow `TerminalView` to request mode/cwd via websocket init payload. -- Add a read-only mode or initial command support. -- Add per-component theme presets or allow app-level defaults. -- Add better telemetry/logging for sidecar startup failures. - -## API Contract - -This section describes the messages across each layer. - -### Client <-> Server (Bun) - -Client -> server: - -- `input` - - `{ type: 'input', data: string }` - - `data` is raw terminal input from xterm. -- `resize` - - `{ type: 'resize', cols: number, rows: number }` - -Server -> client: - -- `output` - - `{ type: 'output', data: string }` - - `data` is raw PTY output to be written to xterm. -- `exit` - - `{ type: 'exit' }` - - Signals terminal process termination. - -### Server <-> Sidecar (Node) - -Server -> sidecar: - -- `init` - - `{ type: 'init', shell, cwd, homeDir, userLabel }` - - `shell`: `{ command: string; args: string[]; name: string }` - - `cwd`: initial current working directory - - `homeDir`: home directory to set in the sidecar - - `userLabel`: email for the prompt template -- `input` - - `{ type: 'input', data: string }` -- `resize` - - `{ type: 'resize', cols: number, rows: number }` - -Sidecar -> server: - -- `output` - - `{ type: 'output', data: string }` -- `exit` - - `{ type: 'exit' }` - -## Sequence Diagram - -``` -Client (xterm) Bun Server Sidecar (Node) Shell - | | | | - | WS connect | | | - |---------------> | | | - | | connect sidecar | | - | |-------------------> | | - | | init (shell/cwd) | | - | |-------------------> | spawn PTY | - | | |----------------->| - | input | | | - |---------------> | input | | - | |-------------------> | write to PTY | - | output | | | - |<--------------- | output | read from PTY | - | |<------------------- | | - | resize | | | - |---------------> | resize | | - | |-------------------> | set PTY size | -``` - -## Docker Troubleshooting - -Common failure modes and checks: - -- Docker not installed or not in PATH - - `ensureDockerImage()` will throw. Install Docker or fix PATH. - -- Image build fails - - Build uses `Dockerfile.terminal-sidecar` and tag `officer-terminal-sidecar:v1`. - - Check for network access (apt), and that build context is the plugin folder. - -- Container starts but sidecar is unreachable - - Container binds to `0.0.0.0`, host maps `127.0.0.1:${port}:${port}`. - - Port is user-specific, stored in `data/terminal-containers.json`. - - Verify with `docker ps` and `docker logs` for the container name. - -- Permissions inside container - - Container runs with host UID/GID derived from the mounted user home. - - If home dir ownership is incorrect, zsh history may fail to write. - -- Shell missing - - Container must have zsh installed; the Dockerfile includes zsh. - - Host mode resolves shell from `$SHELL` or known paths. - -## Per-User Template Rules - -Templates are copied into user home on first launch only. - -Files: - -- `.zshrc` -- `.config/starship-officer.toml` - -Rules: - -- If a file already exists, it is not overwritten. -- This lets the admin provide a stable default while allowing user customization. -- To reset a user to defaults, delete the per-user files and reconnect. diff --git a/src/workspaces/plugins/Terminal/client/Screen/index.tsx b/src/workspaces/plugins/Terminal/client/Screen/index.tsx deleted file mode 100644 index 6cb89dff..00000000 --- a/src/workspaces/plugins/Terminal/client/Screen/index.tsx +++ /dev/null @@ -1,10 +0,0 @@ -import { DashboardLayout } from '@/Screens/Dashboard/Layout'; -import { TerminalView } from '../TerminalView'; - -export const Terminal = () => { - return ( - - - - ); -}; diff --git a/src/workspaces/plugins/Terminal/client/index.ts b/src/workspaces/plugins/Terminal/client/index.ts deleted file mode 100644 index 21942f1b..00000000 --- a/src/workspaces/plugins/Terminal/client/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export { Terminal as Screen } from './Screen'; -export { TerminalView } from './TerminalView'; diff --git a/src/workspaces/plugins/Terminal/index.ts b/src/workspaces/plugins/Terminal/index.ts deleted file mode 100644 index 97fa2046..00000000 --- a/src/workspaces/plugins/Terminal/index.ts +++ /dev/null @@ -1,8 +0,0 @@ -export { Screen } from './client'; -export { terminalWebsocket } from './server'; - -export const plugin = { - id: 'Terminal', - name: 'Terminal', - description: 'Browser-based terminal emulator', -}; diff --git a/src/workspaces/plugins/Terminal/server/index.ts b/src/workspaces/plugins/Terminal/server/index.ts deleted file mode 100644 index 400c5682..00000000 --- a/src/workspaces/plugins/Terminal/server/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { terminalWebsocket } from './websocket'; diff --git a/src/workspaces/plugins/package.json b/src/workspaces/plugins/package.json index fe3d03e0..6c39c333 100644 --- a/src/workspaces/plugins/package.json +++ b/src/workspaces/plugins/package.json @@ -7,9 +7,6 @@ "./FileBrowser": "./FileBrowser/index.ts", "./FileBrowser/client": "./FileBrowser/client/index.ts", "./FileBrowser/server": "./FileBrowser/server/index.ts", - "./Terminal": "./Terminal/index.ts", - "./Terminal/client": "./Terminal/client/index.ts", - "./Terminal/server": "./Terminal/server/index.ts", "./Chat": "./Chat/index.ts", "./Chat/client": "./Chat/client/index.ts", "./ChatHistory": "./ChatHistory/index.ts", diff --git a/src/workspaces/themes/CatppuccinLatte/client.ts b/src/workspaces/themes/CatppuccinLatte/client.ts deleted file mode 100644 index a0bea0e6..00000000 --- a/src/workspaces/themes/CatppuccinLatte/client.ts +++ /dev/null @@ -1,2 +0,0 @@ -import './variables.css'; -import './prose.css'; diff --git a/src/workspaces/themes/CatppuccinLatte/index.ts b/src/workspaces/themes/CatppuccinLatte/index.ts deleted file mode 100644 index 425bfc34..00000000 --- a/src/workspaces/themes/CatppuccinLatte/index.ts +++ /dev/null @@ -1 +0,0 @@ -export const meta = { id: 'CatppuccinLatte', name: 'Catppuccin Latte', description: 'Warm pastel tones on a creamy light canvas.' }; diff --git a/src/workspaces/themes/CatppuccinLatte/prose.css b/src/workspaces/themes/CatppuccinLatte/prose.css deleted file mode 100644 index ca562fa8..00000000 --- a/src/workspaces/themes/CatppuccinLatte/prose.css +++ /dev/null @@ -1,124 +0,0 @@ -/* File Viewer — Markdown Prose */ -[data-color-theme="CatppuccinLatte"] .file-viewer-md { - color: #4c4f69; -} - -[data-color-theme="CatppuccinLatte"] .file-viewer-md h1 { - border-bottom-color: rgba(204, 208, 218, 0.4); -} - -[data-color-theme="CatppuccinLatte"] .file-viewer-md h2 { - border-bottom-color: rgba(204, 208, 218, 0.3); -} - -[data-color-theme="CatppuccinLatte"] .file-viewer-md a { - color: #1e66f5; -} - -[data-color-theme="CatppuccinLatte"] .file-viewer-md a:hover { - color: #04a5e5; -} - -[data-color-theme="CatppuccinLatte"] .file-viewer-md strong { - color: #4c4f69; -} - -[data-color-theme="CatppuccinLatte"] .file-viewer-md blockquote { - border-left-color: #1e66f5; - background: rgba(30, 102, 245, 0.06); - color: #6c6f85; -} - -[data-color-theme="CatppuccinLatte"] .file-viewer-md li::marker { - color: #1e66f5; -} - -[data-color-theme="CatppuccinLatte"] .file-viewer-md hr { - background: rgba(204, 208, 218, 0.4); -} - -[data-color-theme="CatppuccinLatte"] .file-viewer-md th { - background: rgba(30, 102, 245, 0.08); - border-color: rgba(204, 208, 218, 0.4); -} - -[data-color-theme="CatppuccinLatte"] .file-viewer-md td { - border-color: rgba(204, 208, 218, 0.3); -} - -[data-color-theme="CatppuccinLatte"] .file-viewer-md tr:nth-child(even) { - background: rgba(204, 208, 218, 0.1); -} - -[data-color-theme="CatppuccinLatte"] .file-viewer-md input[type="checkbox"] { - accent-color: #1e66f5; -} - -/* Skills — Markdown Prose */ -[data-color-theme="CatppuccinLatte"] .skill-md { - color: #4c4f69; -} - -[data-color-theme="CatppuccinLatte"] .skill-md h1 { - border-bottom-color: rgba(204, 208, 218, 0.4); -} - -[data-color-theme="CatppuccinLatte"] .skill-md h2 { - border-bottom-color: rgba(204, 208, 218, 0.3); -} - -[data-color-theme="CatppuccinLatte"] .skill-md a { - color: #1e66f5; -} - -[data-color-theme="CatppuccinLatte"] .skill-md a:hover { - color: #04a5e5; -} - -[data-color-theme="CatppuccinLatte"] .skill-md strong { - color: #4c4f69; -} - -[data-color-theme="CatppuccinLatte"] .skill-md blockquote { - border-left-color: #1e66f5; - background: rgba(30, 102, 245, 0.06); - color: #6c6f85; -} - -[data-color-theme="CatppuccinLatte"] .skill-md li::marker { - color: #1e66f5; -} - -[data-color-theme="CatppuccinLatte"] .skill-md code { - background: rgba(30, 102, 245, 0.1); - color: #1e66f5; -} - -[data-color-theme="CatppuccinLatte"] .skill-md pre { - background: #e6e9ef; -} - -[data-color-theme="CatppuccinLatte"] .skill-md pre code { - color: #4c4f69; -} - -[data-color-theme="CatppuccinLatte"] .skill-md hr { - background: rgba(204, 208, 218, 0.4); -} - -[data-color-theme="CatppuccinLatte"] .skill-md th { - background: rgba(30, 102, 245, 0.08); - border-color: rgba(204, 208, 218, 0.4); -} - -[data-color-theme="CatppuccinLatte"] .skill-md td { - border-color: rgba(204, 208, 218, 0.3); -} - -[data-color-theme="CatppuccinLatte"] .skill-md tr:nth-child(even) { - background: rgba(204, 208, 218, 0.1); -} - -[data-color-theme="CatppuccinLatte"] .skill-md input[type="checkbox"] { - accent-color: #1e66f5; -} diff --git a/src/workspaces/themes/CatppuccinLatte/variables.css b/src/workspaces/themes/CatppuccinLatte/variables.css deleted file mode 100644 index 6fe4dd30..00000000 --- a/src/workspaces/themes/CatppuccinLatte/variables.css +++ /dev/null @@ -1,92 +0,0 @@ -@layer base { - [data-color-theme="CatppuccinLatte"] { - /* Brand colors */ - --duck-yellow: #df8e1d; - --duck-orange: #d20f39; - --duck-teal: #1e66f5; - --duck-forest: #6c6f85; - --duck-dark: #4c4f69; - --duck-beige: #dce0e8; - - /* Page background */ - --pixel-grid-color: rgba(30, 102, 245, 0.08); - - /* Glass surfaces */ - --glass-bg: rgba(255, 255, 255, 0.1); - --glass-border: rgba(30, 102, 245, 0.2); - --dock-bg: rgba(0, 0, 0, 0.15); - --dock-border: rgba(30, 102, 245, 0.1); - --dock-tooltip-bg: rgba(0, 0, 0, 0.75); - - /* Card component */ - --card-bg: rgba(230, 233, 239, 0.92); - --card-grid-color: rgba(30, 102, 245, 0.06); - - --cta: 219.9 91.5% 53.9%; - --cta-foreground: 220 23.1% 94.9%; - - --naturegreen: 197.1 96.6% 45.7%; - --naturegreen-foreground: 220 23.1% 94.9%; - - --background: 220 23.1% 94.9%; - --foreground: 233.8 16% 35.5%; - - --card: 220 22% 92%; - --card-foreground: 233.8 16% 35.5%; - - --popover: 220 22% 92%; - --popover-foreground: 233.8 16% 35.5%; - - --primary: 219.9 91.5% 53.9%; - --primary-foreground: 220 23.1% 94.9%; - - --secondary: 222.9 15.9% 82.7%; - --secondary-foreground: 233.8 16% 35.5%; - - --muted: 220 20.7% 88.6%; - --muted-foreground: 232.8 10.4% 47.3%; - - --accent: 197.1 96.6% 45.7%; - --accent-foreground: 220 23.1% 94.9%; - - --destructive: 347.1 86.7% 44.1%; - --destructive-foreground: 220 23.1% 94.9%; - - --success: 109.2 57.6% 39.8%; - --success-foreground: 220 23.1% 94.9%; - - --brand: 219.9 91.5% 53.9%; - --brand-foreground: 220 23.1% 94.9%; - --brand-muted: 220 20.7% 88.6%; - - --warning: 34.9 77% 49.4%; - --warning-foreground: 233.8 16% 35.5%; - - --border: 222.9 15.9% 82.7%; - --input: 222.9 15.9% 82.7%; - --ring: 219.9 91.5% 53.9%; - - --radius: 0.5rem; - - /* Chart gradients */ - --chart-primary: 219.9 91.5% 53.9%; - --chart-secondary: 34.9 77% 49.4%; - - /* Status colors */ - --status-success: 109.2 57.6% 39.8%; - --status-warning: 34.9 77% 49.4%; - --status-in-progress: 219.9 91.5% 53.9%; - - --sidebar-background: 220 22% 92%; - --sidebar-foreground: 232.8 10.4% 47.3%; - --sidebar-primary: 219.9 91.5% 53.9%; - --sidebar-primary-foreground: 220 23.1% 94.9%; - --sidebar-accent: 220 20.7% 88.6%; - --sidebar-accent-foreground: 233.8 16% 35.5%; - --sidebar-border: 222.9 15.9% 82.7%; - --sidebar-ring: 219.9 91.5% 53.9%; - - /* Hover Effect */ - --ctahover: 197.1 96.6% 45.7%; - } -} diff --git a/src/workspaces/themes/CatppuccinMocha/client.ts b/src/workspaces/themes/CatppuccinMocha/client.ts deleted file mode 100644 index a0bea0e6..00000000 --- a/src/workspaces/themes/CatppuccinMocha/client.ts +++ /dev/null @@ -1,2 +0,0 @@ -import './variables.css'; -import './prose.css'; diff --git a/src/workspaces/themes/CatppuccinMocha/index.ts b/src/workspaces/themes/CatppuccinMocha/index.ts deleted file mode 100644 index 508cbd11..00000000 --- a/src/workspaces/themes/CatppuccinMocha/index.ts +++ /dev/null @@ -1 +0,0 @@ -export const meta = { id: 'CatppuccinMocha', name: 'Catppuccin Mocha', description: 'Rich dark chocolate with pastel neon accents.' }; diff --git a/src/workspaces/themes/CatppuccinMocha/prose.css b/src/workspaces/themes/CatppuccinMocha/prose.css deleted file mode 100644 index eead51e2..00000000 --- a/src/workspaces/themes/CatppuccinMocha/prose.css +++ /dev/null @@ -1,124 +0,0 @@ -/* File Viewer — Markdown Prose */ -[data-color-theme="CatppuccinMocha"] .file-viewer-md { - color: #cdd6f4; -} - -[data-color-theme="CatppuccinMocha"] .file-viewer-md h1 { - border-bottom-color: rgba(69, 71, 90, 0.4); -} - -[data-color-theme="CatppuccinMocha"] .file-viewer-md h2 { - border-bottom-color: rgba(69, 71, 90, 0.3); -} - -[data-color-theme="CatppuccinMocha"] .file-viewer-md a { - color: #89b4fa; -} - -[data-color-theme="CatppuccinMocha"] .file-viewer-md a:hover { - color: #89dceb; -} - -[data-color-theme="CatppuccinMocha"] .file-viewer-md strong { - color: #cdd6f4; -} - -[data-color-theme="CatppuccinMocha"] .file-viewer-md blockquote { - border-left-color: #89b4fa; - background: rgba(137, 180, 250, 0.06); - color: #7f849c; -} - -[data-color-theme="CatppuccinMocha"] .file-viewer-md li::marker { - color: #89b4fa; -} - -[data-color-theme="CatppuccinMocha"] .file-viewer-md hr { - background: rgba(69, 71, 90, 0.4); -} - -[data-color-theme="CatppuccinMocha"] .file-viewer-md th { - background: rgba(137, 180, 250, 0.08); - border-color: rgba(69, 71, 90, 0.4); -} - -[data-color-theme="CatppuccinMocha"] .file-viewer-md td { - border-color: rgba(69, 71, 90, 0.3); -} - -[data-color-theme="CatppuccinMocha"] .file-viewer-md tr:nth-child(even) { - background: rgba(69, 71, 90, 0.1); -} - -[data-color-theme="CatppuccinMocha"] .file-viewer-md input[type="checkbox"] { - accent-color: #89b4fa; -} - -/* Skills — Markdown Prose */ -[data-color-theme="CatppuccinMocha"] .skill-md { - color: #cdd6f4; -} - -[data-color-theme="CatppuccinMocha"] .skill-md h1 { - border-bottom-color: rgba(69, 71, 90, 0.4); -} - -[data-color-theme="CatppuccinMocha"] .skill-md h2 { - border-bottom-color: rgba(69, 71, 90, 0.3); -} - -[data-color-theme="CatppuccinMocha"] .skill-md a { - color: #89b4fa; -} - -[data-color-theme="CatppuccinMocha"] .skill-md a:hover { - color: #89dceb; -} - -[data-color-theme="CatppuccinMocha"] .skill-md strong { - color: #cdd6f4; -} - -[data-color-theme="CatppuccinMocha"] .skill-md blockquote { - border-left-color: #89b4fa; - background: rgba(137, 180, 250, 0.06); - color: #7f849c; -} - -[data-color-theme="CatppuccinMocha"] .skill-md li::marker { - color: #89b4fa; -} - -[data-color-theme="CatppuccinMocha"] .skill-md code { - background: rgba(137, 180, 250, 0.1); - color: #89b4fa; -} - -[data-color-theme="CatppuccinMocha"] .skill-md pre { - background: #181825; -} - -[data-color-theme="CatppuccinMocha"] .skill-md pre code { - color: #cdd6f4; -} - -[data-color-theme="CatppuccinMocha"] .skill-md hr { - background: rgba(69, 71, 90, 0.4); -} - -[data-color-theme="CatppuccinMocha"] .skill-md th { - background: rgba(137, 180, 250, 0.08); - border-color: rgba(69, 71, 90, 0.4); -} - -[data-color-theme="CatppuccinMocha"] .skill-md td { - border-color: rgba(69, 71, 90, 0.3); -} - -[data-color-theme="CatppuccinMocha"] .skill-md tr:nth-child(even) { - background: rgba(69, 71, 90, 0.1); -} - -[data-color-theme="CatppuccinMocha"] .skill-md input[type="checkbox"] { - accent-color: #89b4fa; -} diff --git a/src/workspaces/themes/CatppuccinMocha/variables.css b/src/workspaces/themes/CatppuccinMocha/variables.css deleted file mode 100644 index f8105097..00000000 --- a/src/workspaces/themes/CatppuccinMocha/variables.css +++ /dev/null @@ -1,92 +0,0 @@ -@layer base { - [data-color-theme="CatppuccinMocha"] { - /* Brand colors */ - --duck-yellow: #f9e2af; - --duck-orange: #fab387; - --duck-teal: #89b4fa; - --duck-forest: #7f849c; - --duck-dark: #cdd6f4; - --duck-beige: #313244; - - /* Page background */ - --pixel-grid-color: rgba(137, 180, 250, 0.06); - - /* Glass surfaces */ - --glass-bg: rgba(0, 0, 0, 0.25); - --glass-border: rgba(137, 180, 250, 0.12); - --dock-bg: rgba(0, 0, 0, 0.35); - --dock-border: rgba(137, 180, 250, 0.08); - --dock-tooltip-bg: rgba(0, 0, 0, 0.9); - - /* Card component */ - --card-bg: rgba(24, 24, 37, 0.92); - --card-grid-color: rgba(137, 180, 250, 0.04); - - --cta: 217.2 91.9% 75.9%; - --cta-foreground: 240 21.1% 14.9%; - - --naturegreen: 189.2 71% 72.9%; - --naturegreen-foreground: 240 21.1% 14.9%; - - --background: 240 21.1% 14.9%; - --foreground: 226.2 63.9% 88%; - - --card: 240 21.3% 12%; - --card-foreground: 226.2 63.9% 88%; - - --popover: 240 21.3% 12%; - --popover-foreground: 226.2 63.9% 88%; - - --primary: 217.2 91.9% 75.9%; - --primary-foreground: 240 21.1% 14.9%; - - --secondary: 234.3 13.2% 31.2%; - --secondary-foreground: 226.2 63.9% 88%; - - --muted: 236.8 16.2% 22.9%; - --muted-foreground: 229.7 12.8% 55.5%; - - --accent: 189.2 71% 72.9%; - --accent-foreground: 240 21.1% 14.9%; - - --destructive: 343.3 81.2% 74.9%; - --destructive-foreground: 240 21.1% 14.9%; - - --success: 115.5 54.1% 76.1%; - --success-foreground: 240 21.1% 14.9%; - - --brand: 217.2 91.9% 75.9%; - --brand-foreground: 240 21.1% 14.9%; - --brand-muted: 236.8 16.2% 22.9%; - - --warning: 41.4 86% 83.1%; - --warning-foreground: 240 21.1% 14.9%; - - --border: 234.3 13.2% 31.2%; - --input: 234.3 13.2% 31.2%; - --ring: 217.2 91.9% 75.9%; - - --radius: 0.5rem; - - /* Chart gradients */ - --chart-primary: 217.2 91.9% 75.9%; - --chart-secondary: 41.4 86% 83.1%; - - /* Status colors */ - --status-success: 115.5 54.1% 76.1%; - --status-warning: 41.4 86% 83.1%; - --status-in-progress: 217.2 91.9% 75.9%; - - --sidebar-background: 240 21.3% 12%; - --sidebar-foreground: 229.7 12.8% 55.5%; - --sidebar-primary: 217.2 91.9% 75.9%; - --sidebar-primary-foreground: 240 21.1% 14.9%; - --sidebar-accent: 236.8 16.2% 22.9%; - --sidebar-accent-foreground: 226.2 63.9% 88%; - --sidebar-border: 234.3 13.2% 31.2%; - --sidebar-ring: 217.2 91.9% 75.9%; - - /* Hover Effect */ - --ctahover: 189.2 71% 72.9%; - } -} diff --git a/src/workspaces/themes/DuckPond/client.ts b/src/workspaces/themes/DuckPond/client.ts deleted file mode 100644 index f6030374..00000000 --- a/src/workspaces/themes/DuckPond/client.ts +++ /dev/null @@ -1,4 +0,0 @@ -import './variables.css'; -import './prose.css'; - -document.documentElement.style.setProperty('--page-bg-image', 'url(/static/landscape1.jpg)'); diff --git a/src/workspaces/themes/DuckPond/index.ts b/src/workspaces/themes/DuckPond/index.ts deleted file mode 100644 index 14af4343..00000000 --- a/src/workspaces/themes/DuckPond/index.ts +++ /dev/null @@ -1 +0,0 @@ -export const meta = { id: 'DuckPond', name: 'Duck Pond', description: 'Warm greens and teals inspired by a forest pond.' }; diff --git a/src/workspaces/themes/DuckPond/variables.css b/src/workspaces/themes/DuckPond/variables.css deleted file mode 100644 index bbfd43b2..00000000 --- a/src/workspaces/themes/DuckPond/variables.css +++ /dev/null @@ -1,164 +0,0 @@ -@layer base { - :root { - /* Duck brand hex colors */ - --duck-yellow: #F4C430; - --duck-orange: #EA580C; - --duck-teal: #0891B2; - --duck-forest: #166534; - --duck-dark: #14532D; - --duck-beige: #E7D4B5; - - /* Page background (--page-bg-image set via client.ts to avoid bundler url() resolution) */ - --pixel-grid-color: rgba(20, 83, 45, 0.1); - - /* Glass surfaces */ - --glass-bg: rgba(255, 255, 255, 0.1); - --glass-border: rgba(255, 255, 255, 0.2); - --dock-bg: rgba(0, 0, 0, 0.15); - --dock-border: rgba(255, 255, 255, 0.1); - --dock-tooltip-bg: rgba(0, 0, 0, 0.75); - - /* Card component */ - --card-bg: rgba(255, 255, 255, 0.9); - --card-grid-color: rgba(20, 83, 45, 0.08); - - --cta: 211 74.77% 45.58%; - --cta-foreground: 0 0% 100%; - - --naturegreen: 145 79% 38%; - --naturegreen-foreground: 0 0% 100%; - - --background: 0 0% 100%; - --foreground: 222.2 84% 4.9%; - - --card: 0 0% 100%; - --card-foreground: 222.2 84% 4.9%; - - --popover: 0 0% 100%; - --popover-foreground: 222.2 84% 4.9%; - - --primary: 222.2 47.4% 11.2%; - --primary-foreground: 210 40% 98%; - - --secondary: 210 40% 96.1%; - --secondary-foreground: 222.2 47.4% 11.2%; - - --muted: 210 40% 96.1%; - --muted-foreground: 215.4 16.3% 46.9%; - - --accent: 211 74.77% 45.58%; - --accent-foreground: 0 0% 0%; - - --destructive: 0 84.2% 60.2%; - --destructive-foreground: 210 40% 98%; - - --success: 142.1 76.2% 36.3%; - --success-foreground: 355.7 100% 97.3%; - - --brand: 145 79% 38%; - --brand-foreground: 0 0% 100%; - --brand-muted: 145 40% 90%; - - --warning: 43 96% 56%; - --warning-foreground: 0 0% 0%; - - --border: 214.3 31.8% 91.4%; - --input: 214.3 31.8% 91.4%; - --ring: 222.2 84% 4.9%; - - --radius: 0.5rem; - - /* Chart gradients */ - --chart-primary: 211 82% 64%; - --chart-secondary: 211 82% 84%; - - /* Status colors */ - --status-success: 142 76% 36%; - --status-warning: 43 96% 56%; - --status-in-progress: 211 82% 64%; - - --sidebar-background: 0 0% 98%; - --sidebar-foreground: 240 5.3% 26.1%; - --sidebar-primary: 240 5.9% 10%; - --sidebar-primary-foreground: 0 0% 98%; - --sidebar-accent: 240 4.8% 95.9%; - --sidebar-accent-foreground: 240 5.9% 10%; - --sidebar-border: 220 13% 91%; - --sidebar-ring: 217.2 91.2% 59.8%; - - /* Hover Effect */ - --ctahover: 211 91.53% 34.82%; - } - - .dark { - /* Page background */ - --pixel-grid-color: rgba(200, 230, 210, 0.08); - - /* Glass surfaces */ - --glass-bg: rgba(0, 0, 0, 0.2); - --glass-border: rgba(255, 255, 255, 0.1); - --dock-bg: rgba(0, 0, 0, 0.3); - --dock-border: rgba(255, 255, 255, 0.08); - --dock-tooltip-bg: rgba(0, 0, 0, 0.85); - - /* Card component */ - --card-bg: rgba(10, 20, 15, 0.9); - --card-grid-color: rgba(200, 230, 210, 0.06); - - --background: 222.2 84% 4.9%; - --foreground: 210 40% 98%; - - --card: 222.2 84% 4.9%; - --card-foreground: 210 40% 98%; - - --popover: 222.2 84% 4.9%; - --popover-foreground: 210 40% 98%; - - --primary: 210 40% 98%; - --primary-foreground: 222.2 47.4% 11.2%; - - --secondary: 217.2 32.6% 17.5%; - --secondary-foreground: 210 40% 98%; - - --muted: 217.2 32.6% 17.5%; - --muted-foreground: 215 20.2% 65.1%; - - --accent: 211 82% 64%; - --accent-foreground: 0 0% 0%; - - --destructive: 0 62.8% 30.6%; - --destructive-foreground: 210 40% 98%; - - --success: 142.1 76.2% 36.3%; - --success-foreground: 355.7 100% 97.3%; - - --brand: 145 60% 45%; - --brand-foreground: 0 0% 100%; - --brand-muted: 145 30% 25%; - - --warning: 43 96% 56%; - --warning-foreground: 0 0% 0%; - - --border: 217.2 32.6% 17.5%; - --input: 217.2 32.6% 17.5%; - --ring: 212.7 26.8% 83.9%; - - /* Chart gradients */ - --chart-primary: 211 82% 64%; - --chart-secondary: 211 82% 84%; - - /* Status colors */ - --status-success: 142 76% 36%; - --status-warning: 43 96% 56%; - --status-in-progress: 211 82% 64%; - - --sidebar-background: 240 5.9% 10%; - --sidebar-foreground: 240 4.8% 95.9%; - --sidebar-primary: 224.3 76.3% 48%; - --sidebar-primary-foreground: 0 0% 100%; - --sidebar-accent: 240 3.7% 15.9%; - --sidebar-accent-foreground: 240 4.8% 95.9%; - --sidebar-border: 240 3.7% 15.9%; - --sidebar-ring: 217.2 91.2% 59.8%; - } -} diff --git a/src/workspaces/themes/Everforest/client.ts b/src/workspaces/themes/Everforest/client.ts deleted file mode 100644 index a0bea0e6..00000000 --- a/src/workspaces/themes/Everforest/client.ts +++ /dev/null @@ -1,2 +0,0 @@ -import './variables.css'; -import './prose.css'; diff --git a/src/workspaces/themes/Everforest/index.ts b/src/workspaces/themes/Everforest/index.ts deleted file mode 100644 index 0ce52f3f..00000000 --- a/src/workspaces/themes/Everforest/index.ts +++ /dev/null @@ -1 +0,0 @@ -export const meta = { id: 'Everforest', name: 'Everforest', description: 'Soft earthy greens from a quiet forest floor.' }; diff --git a/src/workspaces/themes/Everforest/prose.css b/src/workspaces/themes/Everforest/prose.css deleted file mode 100644 index 923d23d9..00000000 --- a/src/workspaces/themes/Everforest/prose.css +++ /dev/null @@ -1,124 +0,0 @@ -/* File Viewer — Markdown Prose */ -[data-color-theme="Everforest"] .file-viewer-md { - color: #d3c6aa; -} - -[data-color-theme="Everforest"] .file-viewer-md h1 { - border-bottom-color: rgba(61, 72, 77, 0.4); -} - -[data-color-theme="Everforest"] .file-viewer-md h2 { - border-bottom-color: rgba(61, 72, 77, 0.3); -} - -[data-color-theme="Everforest"] .file-viewer-md a { - color: #a7c080; -} - -[data-color-theme="Everforest"] .file-viewer-md a:hover { - color: #83c092; -} - -[data-color-theme="Everforest"] .file-viewer-md strong { - color: #d3c6aa; -} - -[data-color-theme="Everforest"] .file-viewer-md blockquote { - border-left-color: #a7c080; - background: rgba(167, 192, 128, 0.06); - color: #859289; -} - -[data-color-theme="Everforest"] .file-viewer-md li::marker { - color: #a7c080; -} - -[data-color-theme="Everforest"] .file-viewer-md hr { - background: rgba(61, 72, 77, 0.4); -} - -[data-color-theme="Everforest"] .file-viewer-md th { - background: rgba(167, 192, 128, 0.08); - border-color: rgba(61, 72, 77, 0.4); -} - -[data-color-theme="Everforest"] .file-viewer-md td { - border-color: rgba(61, 72, 77, 0.3); -} - -[data-color-theme="Everforest"] .file-viewer-md tr:nth-child(even) { - background: rgba(61, 72, 77, 0.1); -} - -[data-color-theme="Everforest"] .file-viewer-md input[type="checkbox"] { - accent-color: #a7c080; -} - -/* Skills — Markdown Prose */ -[data-color-theme="Everforest"] .skill-md { - color: #d3c6aa; -} - -[data-color-theme="Everforest"] .skill-md h1 { - border-bottom-color: rgba(61, 72, 77, 0.4); -} - -[data-color-theme="Everforest"] .skill-md h2 { - border-bottom-color: rgba(61, 72, 77, 0.3); -} - -[data-color-theme="Everforest"] .skill-md a { - color: #a7c080; -} - -[data-color-theme="Everforest"] .skill-md a:hover { - color: #83c092; -} - -[data-color-theme="Everforest"] .skill-md strong { - color: #d3c6aa; -} - -[data-color-theme="Everforest"] .skill-md blockquote { - border-left-color: #a7c080; - background: rgba(167, 192, 128, 0.06); - color: #859289; -} - -[data-color-theme="Everforest"] .skill-md li::marker { - color: #a7c080; -} - -[data-color-theme="Everforest"] .skill-md code { - background: rgba(167, 192, 128, 0.1); - color: #a7c080; -} - -[data-color-theme="Everforest"] .skill-md pre { - background: #272e33; -} - -[data-color-theme="Everforest"] .skill-md pre code { - color: #d3c6aa; -} - -[data-color-theme="Everforest"] .skill-md hr { - background: rgba(61, 72, 77, 0.4); -} - -[data-color-theme="Everforest"] .skill-md th { - background: rgba(167, 192, 128, 0.08); - border-color: rgba(61, 72, 77, 0.4); -} - -[data-color-theme="Everforest"] .skill-md td { - border-color: rgba(61, 72, 77, 0.3); -} - -[data-color-theme="Everforest"] .skill-md tr:nth-child(even) { - background: rgba(61, 72, 77, 0.1); -} - -[data-color-theme="Everforest"] .skill-md input[type="checkbox"] { - accent-color: #a7c080; -} diff --git a/src/workspaces/themes/Everforest/variables.css b/src/workspaces/themes/Everforest/variables.css deleted file mode 100644 index 0970a235..00000000 --- a/src/workspaces/themes/Everforest/variables.css +++ /dev/null @@ -1,92 +0,0 @@ -@layer base { - [data-color-theme="Everforest"] { - /* Brand colors */ - --duck-yellow: #dbbc7f; - --duck-orange: #e69875; - --duck-teal: #a7c080; - --duck-forest: #859289; - --duck-dark: #d3c6aa; - --duck-beige: #374247; - - /* Page background */ - --pixel-grid-color: rgba(167, 192, 128, 0.06); - - /* Glass surfaces */ - --glass-bg: rgba(0, 0, 0, 0.25); - --glass-border: rgba(167, 192, 128, 0.12); - --dock-bg: rgba(0, 0, 0, 0.35); - --dock-border: rgba(167, 192, 128, 0.08); - --dock-tooltip-bg: rgba(0, 0, 0, 0.9); - - /* Card component */ - --card-bg: rgba(39, 46, 51, 0.92); - --card-grid-color: rgba(167, 192, 128, 0.04); - - --cta: 83.4 33.7% 62.7%; - --cta-foreground: 205.7 13.5% 20.4%; - - --naturegreen: 134.8 32.6% 63.3%; - --naturegreen-foreground: 205.7 13.5% 20.4%; - - --background: 205.7 13.5% 20.4%; - --foreground: 41 31.8% 74.7%; - - --card: 205 13.3% 17.6%; - --card-foreground: 41 31.8% 74.7%; - - --popover: 205 13.3% 17.6%; - --popover-foreground: 41 31.8% 74.7%; - - --primary: 83.4 33.7% 62.7%; - --primary-foreground: 205.7 13.5% 20.4%; - - --secondary: 198.8 11.6% 27.1%; - --secondary-foreground: 41 31.8% 74.7%; - - --muted: 198.8 12.7% 24.7%; - --muted-foreground: 138.5 5.6% 54.7%; - - --accent: 134.8 32.6% 63.3%; - --accent-foreground: 205.7 13.5% 20.4%; - - --destructive: 358.8 67.5% 69.8%; - --destructive-foreground: 41 31.8% 74.7%; - - --success: 134.8 32.6% 63.3%; - --success-foreground: 205.7 13.5% 20.4%; - - --brand: 83.4 33.7% 62.7%; - --brand-foreground: 205.7 13.5% 20.4%; - --brand-muted: 198.8 12.7% 24.7%; - - --warning: 39.8 56.1% 67.8%; - --warning-foreground: 205.7 13.5% 20.4%; - - --border: 198.8 11.6% 27.1%; - --input: 198.8 11.6% 27.1%; - --ring: 83.4 33.7% 62.7%; - - --radius: 0.5rem; - - /* Chart gradients */ - --chart-primary: 83.4 33.7% 62.7%; - --chart-secondary: 39.8 56.1% 67.8%; - - /* Status colors */ - --status-success: 134.8 32.6% 63.3%; - --status-warning: 39.8 56.1% 67.8%; - --status-in-progress: 83.4 33.7% 62.7%; - - --sidebar-background: 205 13.3% 17.6%; - --sidebar-foreground: 138.5 5.6% 54.7%; - --sidebar-primary: 83.4 33.7% 62.7%; - --sidebar-primary-foreground: 205.7 13.5% 20.4%; - --sidebar-accent: 198.8 12.7% 24.7%; - --sidebar-accent-foreground: 41 31.8% 74.7%; - --sidebar-border: 198.8 11.6% 27.1%; - --sidebar-ring: 83.4 33.7% 62.7%; - - /* Hover Effect */ - --ctahover: 134.8 32.6% 63.3%; - } -} diff --git a/src/workspaces/themes/Gruvbox/client.ts b/src/workspaces/themes/Gruvbox/client.ts deleted file mode 100644 index a0bea0e6..00000000 --- a/src/workspaces/themes/Gruvbox/client.ts +++ /dev/null @@ -1,2 +0,0 @@ -import './variables.css'; -import './prose.css'; diff --git a/src/workspaces/themes/Gruvbox/index.ts b/src/workspaces/themes/Gruvbox/index.ts deleted file mode 100644 index 44b1a4eb..00000000 --- a/src/workspaces/themes/Gruvbox/index.ts +++ /dev/null @@ -1 +0,0 @@ -export const meta = { id: 'Gruvbox', name: 'Gruvbox', description: 'Retro warm tones with earthy browns and muted accents.' }; diff --git a/src/workspaces/themes/Gruvbox/prose.css b/src/workspaces/themes/Gruvbox/prose.css deleted file mode 100644 index 943ef0e0..00000000 --- a/src/workspaces/themes/Gruvbox/prose.css +++ /dev/null @@ -1,124 +0,0 @@ -/* File Viewer — Markdown Prose */ -[data-color-theme="Gruvbox"] .file-viewer-md { - color: #ebdbb2; -} - -[data-color-theme="Gruvbox"] .file-viewer-md h1 { - border-bottom-color: rgba(80, 73, 69, 0.4); -} - -[data-color-theme="Gruvbox"] .file-viewer-md h2 { - border-bottom-color: rgba(80, 73, 69, 0.3); -} - -[data-color-theme="Gruvbox"] .file-viewer-md a { - color: #83a598; -} - -[data-color-theme="Gruvbox"] .file-viewer-md a:hover { - color: #8ec07c; -} - -[data-color-theme="Gruvbox"] .file-viewer-md strong { - color: #ebdbb2; -} - -[data-color-theme="Gruvbox"] .file-viewer-md blockquote { - border-left-color: #83a598; - background: rgba(131, 165, 152, 0.06); - color: #a89984; -} - -[data-color-theme="Gruvbox"] .file-viewer-md li::marker { - color: #83a598; -} - -[data-color-theme="Gruvbox"] .file-viewer-md hr { - background: rgba(80, 73, 69, 0.4); -} - -[data-color-theme="Gruvbox"] .file-viewer-md th { - background: rgba(131, 165, 152, 0.08); - border-color: rgba(80, 73, 69, 0.4); -} - -[data-color-theme="Gruvbox"] .file-viewer-md td { - border-color: rgba(80, 73, 69, 0.3); -} - -[data-color-theme="Gruvbox"] .file-viewer-md tr:nth-child(even) { - background: rgba(80, 73, 69, 0.1); -} - -[data-color-theme="Gruvbox"] .file-viewer-md input[type="checkbox"] { - accent-color: #83a598; -} - -/* Skills — Markdown Prose */ -[data-color-theme="Gruvbox"] .skill-md { - color: #ebdbb2; -} - -[data-color-theme="Gruvbox"] .skill-md h1 { - border-bottom-color: rgba(80, 73, 69, 0.4); -} - -[data-color-theme="Gruvbox"] .skill-md h2 { - border-bottom-color: rgba(80, 73, 69, 0.3); -} - -[data-color-theme="Gruvbox"] .skill-md a { - color: #83a598; -} - -[data-color-theme="Gruvbox"] .skill-md a:hover { - color: #8ec07c; -} - -[data-color-theme="Gruvbox"] .skill-md strong { - color: #ebdbb2; -} - -[data-color-theme="Gruvbox"] .skill-md blockquote { - border-left-color: #83a598; - background: rgba(131, 165, 152, 0.06); - color: #a89984; -} - -[data-color-theme="Gruvbox"] .skill-md li::marker { - color: #83a598; -} - -[data-color-theme="Gruvbox"] .skill-md code { - background: rgba(131, 165, 152, 0.1); - color: #83a598; -} - -[data-color-theme="Gruvbox"] .skill-md pre { - background: #1d2021; -} - -[data-color-theme="Gruvbox"] .skill-md pre code { - color: #ebdbb2; -} - -[data-color-theme="Gruvbox"] .skill-md hr { - background: rgba(80, 73, 69, 0.4); -} - -[data-color-theme="Gruvbox"] .skill-md th { - background: rgba(131, 165, 152, 0.08); - border-color: rgba(80, 73, 69, 0.4); -} - -[data-color-theme="Gruvbox"] .skill-md td { - border-color: rgba(80, 73, 69, 0.3); -} - -[data-color-theme="Gruvbox"] .skill-md tr:nth-child(even) { - background: rgba(80, 73, 69, 0.1); -} - -[data-color-theme="Gruvbox"] .skill-md input[type="checkbox"] { - accent-color: #83a598; -} diff --git a/src/workspaces/themes/Gruvbox/variables.css b/src/workspaces/themes/Gruvbox/variables.css deleted file mode 100644 index c803901d..00000000 --- a/src/workspaces/themes/Gruvbox/variables.css +++ /dev/null @@ -1,92 +0,0 @@ -@layer base { - [data-color-theme="Gruvbox"] { - /* Brand colors */ - --duck-yellow: #fabd2f; - --duck-orange: #fe8019; - --duck-teal: #83a598; - --duck-forest: #a89984; - --duck-dark: #ebdbb2; - --duck-beige: #3c3836; - - /* Page background */ - --pixel-grid-color: rgba(131, 165, 152, 0.06); - - /* Glass surfaces */ - --glass-bg: rgba(0, 0, 0, 0.25); - --glass-border: rgba(131, 165, 152, 0.12); - --dock-bg: rgba(0, 0, 0, 0.35); - --dock-border: rgba(131, 165, 152, 0.08); - --dock-tooltip-bg: rgba(0, 0, 0, 0.9); - - /* Card component */ - --card-bg: rgba(29, 32, 33, 0.92); - --card-grid-color: rgba(131, 165, 152, 0.04); - - --cta: 157.1 15.9% 58%; - --cta-foreground: 0 0% 15.7%; - - --naturegreen: 104.1 35.1% 62%; - --naturegreen-foreground: 0 0% 15.7%; - - --background: 0 0% 15.7%; - --foreground: 43.2 58.8% 81%; - - --card: 195 6.5% 12.2%; - --card-foreground: 43.2 58.8% 81%; - - --popover: 195 6.5% 12.2%; - --popover-foreground: 43.2 58.8% 81%; - - --primary: 157.1 15.9% 58%; - --primary-foreground: 0 0% 15.7%; - - --secondary: 21.8 7.4% 29.2%; - --secondary-foreground: 43.2 58.8% 81%; - - --muted: 20 5.3% 22.4%; - --muted-foreground: 35 17.1% 58.8%; - - --accent: 104.1 35.1% 62%; - --accent-foreground: 0 0% 15.7%; - - --destructive: 6.3 96.1% 59.4%; - --destructive-foreground: 43.2 58.8% 81%; - - --success: 61.2 66.2% 44.1%; - --success-foreground: 0 0% 15.7%; - - --brand: 157.1 15.9% 58%; - --brand-foreground: 0 0% 15.7%; - --brand-muted: 20 5.3% 22.4%; - - --warning: 42 95.3% 58.2%; - --warning-foreground: 0 0% 15.7%; - - --border: 21.8 7.4% 29.2%; - --input: 21.8 7.4% 29.2%; - --ring: 157.1 15.9% 58%; - - --radius: 0.5rem; - - /* Chart gradients */ - --chart-primary: 157.1 15.9% 58%; - --chart-secondary: 42 95.3% 58.2%; - - /* Status colors */ - --status-success: 61.2 66.2% 44.1%; - --status-warning: 42 95.3% 58.2%; - --status-in-progress: 157.1 15.9% 58%; - - --sidebar-background: 195 6.5% 12.2%; - --sidebar-foreground: 35 17.1% 58.8%; - --sidebar-primary: 157.1 15.9% 58%; - --sidebar-primary-foreground: 0 0% 15.7%; - --sidebar-accent: 20 5.3% 22.4%; - --sidebar-accent-foreground: 43.2 58.8% 81%; - --sidebar-border: 21.8 7.4% 29.2%; - --sidebar-ring: 157.1 15.9% 58%; - - /* Hover Effect */ - --ctahover: 104.1 35.1% 62%; - } -} diff --git a/src/workspaces/themes/Kanagawa/client.ts b/src/workspaces/themes/Kanagawa/client.ts deleted file mode 100644 index a0bea0e6..00000000 --- a/src/workspaces/themes/Kanagawa/client.ts +++ /dev/null @@ -1,2 +0,0 @@ -import './variables.css'; -import './prose.css'; diff --git a/src/workspaces/themes/Kanagawa/index.ts b/src/workspaces/themes/Kanagawa/index.ts deleted file mode 100644 index cd729bda..00000000 --- a/src/workspaces/themes/Kanagawa/index.ts +++ /dev/null @@ -1 +0,0 @@ -export const meta = { id: 'Kanagawa', name: 'Kanagawa', description: 'Deep indigo waves and ink-wash inspired hues.' }; diff --git a/src/workspaces/themes/Kanagawa/prose.css b/src/workspaces/themes/Kanagawa/prose.css deleted file mode 100644 index 8d347167..00000000 --- a/src/workspaces/themes/Kanagawa/prose.css +++ /dev/null @@ -1,124 +0,0 @@ -/* File Viewer — Markdown Prose */ -[data-color-theme="Kanagawa"] .file-viewer-md { - color: #dcd7ba; -} - -[data-color-theme="Kanagawa"] .file-viewer-md h1 { - border-bottom-color: rgba(42, 42, 55, 0.4); -} - -[data-color-theme="Kanagawa"] .file-viewer-md h2 { - border-bottom-color: rgba(42, 42, 55, 0.3); -} - -[data-color-theme="Kanagawa"] .file-viewer-md a { - color: #7e9cd8; -} - -[data-color-theme="Kanagawa"] .file-viewer-md a:hover { - color: #7fb4ca; -} - -[data-color-theme="Kanagawa"] .file-viewer-md strong { - color: #dcd7ba; -} - -[data-color-theme="Kanagawa"] .file-viewer-md blockquote { - border-left-color: #7e9cd8; - background: rgba(126, 156, 216, 0.06); - color: #727169; -} - -[data-color-theme="Kanagawa"] .file-viewer-md li::marker { - color: #7e9cd8; -} - -[data-color-theme="Kanagawa"] .file-viewer-md hr { - background: rgba(42, 42, 55, 0.4); -} - -[data-color-theme="Kanagawa"] .file-viewer-md th { - background: rgba(126, 156, 216, 0.08); - border-color: rgba(42, 42, 55, 0.4); -} - -[data-color-theme="Kanagawa"] .file-viewer-md td { - border-color: rgba(42, 42, 55, 0.3); -} - -[data-color-theme="Kanagawa"] .file-viewer-md tr:nth-child(even) { - background: rgba(42, 42, 55, 0.1); -} - -[data-color-theme="Kanagawa"] .file-viewer-md input[type="checkbox"] { - accent-color: #7e9cd8; -} - -/* Skills — Markdown Prose */ -[data-color-theme="Kanagawa"] .skill-md { - color: #dcd7ba; -} - -[data-color-theme="Kanagawa"] .skill-md h1 { - border-bottom-color: rgba(42, 42, 55, 0.4); -} - -[data-color-theme="Kanagawa"] .skill-md h2 { - border-bottom-color: rgba(42, 42, 55, 0.3); -} - -[data-color-theme="Kanagawa"] .skill-md a { - color: #7e9cd8; -} - -[data-color-theme="Kanagawa"] .skill-md a:hover { - color: #7fb4ca; -} - -[data-color-theme="Kanagawa"] .skill-md strong { - color: #dcd7ba; -} - -[data-color-theme="Kanagawa"] .skill-md blockquote { - border-left-color: #7e9cd8; - background: rgba(126, 156, 216, 0.06); - color: #727169; -} - -[data-color-theme="Kanagawa"] .skill-md li::marker { - color: #7e9cd8; -} - -[data-color-theme="Kanagawa"] .skill-md code { - background: rgba(126, 156, 216, 0.1); - color: #7e9cd8; -} - -[data-color-theme="Kanagawa"] .skill-md pre { - background: #16161d; -} - -[data-color-theme="Kanagawa"] .skill-md pre code { - color: #dcd7ba; -} - -[data-color-theme="Kanagawa"] .skill-md hr { - background: rgba(42, 42, 55, 0.4); -} - -[data-color-theme="Kanagawa"] .skill-md th { - background: rgba(126, 156, 216, 0.08); - border-color: rgba(42, 42, 55, 0.4); -} - -[data-color-theme="Kanagawa"] .skill-md td { - border-color: rgba(42, 42, 55, 0.3); -} - -[data-color-theme="Kanagawa"] .skill-md tr:nth-child(even) { - background: rgba(42, 42, 55, 0.1); -} - -[data-color-theme="Kanagawa"] .skill-md input[type="checkbox"] { - accent-color: #7e9cd8; -} diff --git a/src/workspaces/themes/Kanagawa/variables.css b/src/workspaces/themes/Kanagawa/variables.css deleted file mode 100644 index 3737ca1a..00000000 --- a/src/workspaces/themes/Kanagawa/variables.css +++ /dev/null @@ -1,92 +0,0 @@ -@layer base { - [data-color-theme="Kanagawa"] { - /* Brand colors */ - --duck-yellow: #ffa066; - --duck-orange: #ff5d62; - --duck-teal: #7e9cd8; - --duck-forest: #727169; - --duck-dark: #dcd7ba; - --duck-beige: #223249; - - /* Page background */ - --pixel-grid-color: rgba(126, 156, 216, 0.06); - - /* Glass surfaces */ - --glass-bg: rgba(0, 0, 0, 0.25); - --glass-border: rgba(126, 156, 216, 0.12); - --dock-bg: rgba(0, 0, 0, 0.35); - --dock-border: rgba(126, 156, 216, 0.08); - --dock-tooltip-bg: rgba(0, 0, 0, 0.9); - - /* Card component */ - --card-bg: rgba(22, 22, 29, 0.92); - --card-grid-color: rgba(126, 156, 216, 0.04); - - --cta: 220 53.6% 67.1%; - --cta-foreground: 240 12.7% 13.9%; - - --naturegreen: 197.6 41.4% 64.5%; - --naturegreen-foreground: 240 12.7% 13.9%; - - --background: 240 12.7% 13.9%; - --foreground: 51.2 32.7% 79.6%; - - --card: 240 13.7% 10%; - --card-foreground: 51.2 32.7% 79.6%; - - --popover: 240 13.7% 10%; - --popover-foreground: 51.2 32.7% 79.6%; - - --primary: 220 53.6% 67.1%; - --primary-foreground: 240 12.7% 13.9%; - - --secondary: 240 13.4% 19%; - --secondary-foreground: 51.2 32.7% 79.6%; - - --muted: 215.4 36.4% 21%; - --muted-foreground: 53.3 4.1% 42.9%; - - --accent: 197.6 41.4% 64.5%; - --accent-foreground: 240 12.7% 13.9%; - - --destructive: 0 81% 52.5%; - --destructive-foreground: 51.2 32.7% 79.6%; - - --success: 86.6 36.7% 57.8%; - --success-foreground: 240 12.7% 13.9%; - - --brand: 220 53.6% 67.1%; - --brand-foreground: 240 12.7% 13.9%; - --brand-muted: 215.4 36.4% 21%; - - --warning: 22.7 100% 70%; - --warning-foreground: 240 12.7% 13.9%; - - --border: 240 13.4% 19%; - --input: 240 13.4% 19%; - --ring: 220 53.6% 67.1%; - - --radius: 0.5rem; - - /* Chart gradients */ - --chart-primary: 220 53.6% 67.1%; - --chart-secondary: 22.7 100% 70%; - - /* Status colors */ - --status-success: 86.6 36.7% 57.8%; - --status-warning: 22.7 100% 70%; - --status-in-progress: 220 53.6% 67.1%; - - --sidebar-background: 240 13.7% 10%; - --sidebar-foreground: 53.3 4.1% 42.9%; - --sidebar-primary: 220 53.6% 67.1%; - --sidebar-primary-foreground: 240 12.7% 13.9%; - --sidebar-accent: 215.4 36.4% 21%; - --sidebar-accent-foreground: 51.2 32.7% 79.6%; - --sidebar-border: 240 13.4% 19%; - --sidebar-ring: 220 53.6% 67.1%; - - /* Hover Effect */ - --ctahover: 197.6 41.4% 64.5%; - } -} diff --git a/src/workspaces/themes/MatteBlack/client.ts b/src/workspaces/themes/MatteBlack/client.ts deleted file mode 100644 index a0bea0e6..00000000 --- a/src/workspaces/themes/MatteBlack/client.ts +++ /dev/null @@ -1,2 +0,0 @@ -import './variables.css'; -import './prose.css'; diff --git a/src/workspaces/themes/MatteBlack/index.ts b/src/workspaces/themes/MatteBlack/index.ts deleted file mode 100644 index 9e06c02e..00000000 --- a/src/workspaces/themes/MatteBlack/index.ts +++ /dev/null @@ -1 +0,0 @@ -export const meta = { id: 'MatteBlack', name: 'Matte Black', description: 'Pure minimal monochrome with a matte finish.' }; diff --git a/src/workspaces/themes/MatteBlack/prose.css b/src/workspaces/themes/MatteBlack/prose.css deleted file mode 100644 index a3135306..00000000 --- a/src/workspaces/themes/MatteBlack/prose.css +++ /dev/null @@ -1,124 +0,0 @@ -/* File Viewer — Markdown Prose */ -[data-color-theme="MatteBlack"] .file-viewer-md { - color: #e0e0e0; -} - -[data-color-theme="MatteBlack"] .file-viewer-md h1 { - border-bottom-color: rgba(42, 42, 42, 0.4); -} - -[data-color-theme="MatteBlack"] .file-viewer-md h2 { - border-bottom-color: rgba(42, 42, 42, 0.3); -} - -[data-color-theme="MatteBlack"] .file-viewer-md a { - color: #ffffff; -} - -[data-color-theme="MatteBlack"] .file-viewer-md a:hover { - color: #d0d0d0; -} - -[data-color-theme="MatteBlack"] .file-viewer-md strong { - color: #e0e0e0; -} - -[data-color-theme="MatteBlack"] .file-viewer-md blockquote { - border-left-color: #ffffff; - background: rgba(255, 255, 255, 0.06); - color: #9a9a9a; -} - -[data-color-theme="MatteBlack"] .file-viewer-md li::marker { - color: #ffffff; -} - -[data-color-theme="MatteBlack"] .file-viewer-md hr { - background: rgba(42, 42, 42, 0.4); -} - -[data-color-theme="MatteBlack"] .file-viewer-md th { - background: rgba(255, 255, 255, 0.08); - border-color: rgba(42, 42, 42, 0.4); -} - -[data-color-theme="MatteBlack"] .file-viewer-md td { - border-color: rgba(42, 42, 42, 0.3); -} - -[data-color-theme="MatteBlack"] .file-viewer-md tr:nth-child(even) { - background: rgba(42, 42, 42, 0.1); -} - -[data-color-theme="MatteBlack"] .file-viewer-md input[type="checkbox"] { - accent-color: #ffffff; -} - -/* Skills — Markdown Prose */ -[data-color-theme="MatteBlack"] .skill-md { - color: #e0e0e0; -} - -[data-color-theme="MatteBlack"] .skill-md h1 { - border-bottom-color: rgba(42, 42, 42, 0.4); -} - -[data-color-theme="MatteBlack"] .skill-md h2 { - border-bottom-color: rgba(42, 42, 42, 0.3); -} - -[data-color-theme="MatteBlack"] .skill-md a { - color: #ffffff; -} - -[data-color-theme="MatteBlack"] .skill-md a:hover { - color: #d0d0d0; -} - -[data-color-theme="MatteBlack"] .skill-md strong { - color: #e0e0e0; -} - -[data-color-theme="MatteBlack"] .skill-md blockquote { - border-left-color: #ffffff; - background: rgba(255, 255, 255, 0.06); - color: #9a9a9a; -} - -[data-color-theme="MatteBlack"] .skill-md li::marker { - color: #ffffff; -} - -[data-color-theme="MatteBlack"] .skill-md code { - background: rgba(255, 255, 255, 0.1); - color: #ffffff; -} - -[data-color-theme="MatteBlack"] .skill-md pre { - background: #121212; -} - -[data-color-theme="MatteBlack"] .skill-md pre code { - color: #e0e0e0; -} - -[data-color-theme="MatteBlack"] .skill-md hr { - background: rgba(42, 42, 42, 0.4); -} - -[data-color-theme="MatteBlack"] .skill-md th { - background: rgba(255, 255, 255, 0.08); - border-color: rgba(42, 42, 42, 0.4); -} - -[data-color-theme="MatteBlack"] .skill-md td { - border-color: rgba(42, 42, 42, 0.3); -} - -[data-color-theme="MatteBlack"] .skill-md tr:nth-child(even) { - background: rgba(42, 42, 42, 0.1); -} - -[data-color-theme="MatteBlack"] .skill-md input[type="checkbox"] { - accent-color: #ffffff; -} diff --git a/src/workspaces/themes/MatteBlack/variables.css b/src/workspaces/themes/MatteBlack/variables.css deleted file mode 100644 index 06e532b4..00000000 --- a/src/workspaces/themes/MatteBlack/variables.css +++ /dev/null @@ -1,92 +0,0 @@ -@layer base { - [data-color-theme="MatteBlack"] { - /* Brand colors */ - --duck-yellow: #e0e0e0; - --duck-orange: #cccccc; - --duck-teal: #ffffff; - --duck-forest: #9a9a9a; - --duck-dark: #e0e0e0; - --duck-beige: #1a1a1a; - - /* Page background */ - --pixel-grid-color: rgba(255, 255, 255, 0.06); - - /* Glass surfaces */ - --glass-bg: rgba(0, 0, 0, 0.25); - --glass-border: rgba(255, 255, 255, 0.12); - --dock-bg: rgba(0, 0, 0, 0.35); - --dock-border: rgba(255, 255, 255, 0.08); - --dock-tooltip-bg: rgba(0, 0, 0, 0.9); - - /* Card component */ - --card-bg: rgba(18, 18, 18, 0.92); - --card-grid-color: rgba(255, 255, 255, 0.04); - - --cta: 0 0% 100%; - --cta-foreground: 0 0% 3.9%; - - --naturegreen: 0 0% 81.6%; - --naturegreen-foreground: 0 0% 3.9%; - - --background: 0 0% 3.9%; - --foreground: 0 0% 87.8%; - - --card: 0 0% 7.1%; - --card-foreground: 0 0% 87.8%; - - --popover: 0 0% 7.1%; - --popover-foreground: 0 0% 87.8%; - - --primary: 0 0% 100%; - --primary-foreground: 0 0% 3.9%; - - --secondary: 0 0% 16.5%; - --secondary-foreground: 0 0% 87.8%; - - --muted: 0 0% 10.2%; - --muted-foreground: 0 0% 60.4%; - - --accent: 0 0% 81.6%; - --accent-foreground: 0 0% 3.9%; - - --destructive: 0 100% 63.3%; - --destructive-foreground: 0 0% 87.8%; - - --success: 0 0% 60%; - --success-foreground: 0 0% 3.9%; - - --brand: 0 0% 100%; - --brand-foreground: 0 0% 3.9%; - --brand-muted: 0 0% 10.2%; - - --warning: 0 0% 80%; - --warning-foreground: 0 0% 3.9%; - - --border: 0 0% 16.5%; - --input: 0 0% 16.5%; - --ring: 0 0% 100%; - - --radius: 0.5rem; - - /* Chart gradients */ - --chart-primary: 0 0% 100%; - --chart-secondary: 0 0% 80%; - - /* Status colors */ - --status-success: 0 0% 60%; - --status-warning: 0 0% 80%; - --status-in-progress: 0 0% 100%; - - --sidebar-background: 0 0% 7.1%; - --sidebar-foreground: 0 0% 60.4%; - --sidebar-primary: 0 0% 100%; - --sidebar-primary-foreground: 0 0% 3.9%; - --sidebar-accent: 0 0% 10.2%; - --sidebar-accent-foreground: 0 0% 87.8%; - --sidebar-border: 0 0% 16.5%; - --sidebar-ring: 0 0% 100%; - - /* Hover Effect */ - --ctahover: 0 0% 81.6%; - } -} diff --git a/src/workspaces/themes/Nord/client.ts b/src/workspaces/themes/Nord/client.ts deleted file mode 100644 index a0bea0e6..00000000 --- a/src/workspaces/themes/Nord/client.ts +++ /dev/null @@ -1,2 +0,0 @@ -import './variables.css'; -import './prose.css'; diff --git a/src/workspaces/themes/Nord/index.ts b/src/workspaces/themes/Nord/index.ts deleted file mode 100644 index e85dc88b..00000000 --- a/src/workspaces/themes/Nord/index.ts +++ /dev/null @@ -1 +0,0 @@ -export const meta = { id: 'Nord', name: 'Nord', description: 'Cool arctic blues and frosty Nordic tones.' }; diff --git a/src/workspaces/themes/Nord/prose.css b/src/workspaces/themes/Nord/prose.css deleted file mode 100644 index f901fc71..00000000 --- a/src/workspaces/themes/Nord/prose.css +++ /dev/null @@ -1,124 +0,0 @@ -/* File Viewer — Markdown Prose */ -[data-color-theme="Nord"] .file-viewer-md { - color: #eceff4; -} - -[data-color-theme="Nord"] .file-viewer-md h1 { - border-bottom-color: rgba(67, 76, 94, 0.4); -} - -[data-color-theme="Nord"] .file-viewer-md h2 { - border-bottom-color: rgba(67, 76, 94, 0.3); -} - -[data-color-theme="Nord"] .file-viewer-md a { - color: #88c0d0; -} - -[data-color-theme="Nord"] .file-viewer-md a:hover { - color: #8fbcbb; -} - -[data-color-theme="Nord"] .file-viewer-md strong { - color: #eceff4; -} - -[data-color-theme="Nord"] .file-viewer-md blockquote { - border-left-color: #88c0d0; - background: rgba(136, 192, 208, 0.06); - color: #d8dee9; -} - -[data-color-theme="Nord"] .file-viewer-md li::marker { - color: #88c0d0; -} - -[data-color-theme="Nord"] .file-viewer-md hr { - background: rgba(67, 76, 94, 0.4); -} - -[data-color-theme="Nord"] .file-viewer-md th { - background: rgba(136, 192, 208, 0.08); - border-color: rgba(67, 76, 94, 0.4); -} - -[data-color-theme="Nord"] .file-viewer-md td { - border-color: rgba(67, 76, 94, 0.3); -} - -[data-color-theme="Nord"] .file-viewer-md tr:nth-child(even) { - background: rgba(67, 76, 94, 0.1); -} - -[data-color-theme="Nord"] .file-viewer-md input[type="checkbox"] { - accent-color: #88c0d0; -} - -/* Skills — Markdown Prose */ -[data-color-theme="Nord"] .skill-md { - color: #eceff4; -} - -[data-color-theme="Nord"] .skill-md h1 { - border-bottom-color: rgba(67, 76, 94, 0.4); -} - -[data-color-theme="Nord"] .skill-md h2 { - border-bottom-color: rgba(67, 76, 94, 0.3); -} - -[data-color-theme="Nord"] .skill-md a { - color: #88c0d0; -} - -[data-color-theme="Nord"] .skill-md a:hover { - color: #8fbcbb; -} - -[data-color-theme="Nord"] .skill-md strong { - color: #eceff4; -} - -[data-color-theme="Nord"] .skill-md blockquote { - border-left-color: #88c0d0; - background: rgba(136, 192, 208, 0.06); - color: #d8dee9; -} - -[data-color-theme="Nord"] .skill-md li::marker { - color: #88c0d0; -} - -[data-color-theme="Nord"] .skill-md code { - background: rgba(136, 192, 208, 0.1); - color: #88c0d0; -} - -[data-color-theme="Nord"] .skill-md pre { - background: #3b4252; -} - -[data-color-theme="Nord"] .skill-md pre code { - color: #eceff4; -} - -[data-color-theme="Nord"] .skill-md hr { - background: rgba(67, 76, 94, 0.4); -} - -[data-color-theme="Nord"] .skill-md th { - background: rgba(136, 192, 208, 0.08); - border-color: rgba(67, 76, 94, 0.4); -} - -[data-color-theme="Nord"] .skill-md td { - border-color: rgba(67, 76, 94, 0.3); -} - -[data-color-theme="Nord"] .skill-md tr:nth-child(even) { - background: rgba(67, 76, 94, 0.1); -} - -[data-color-theme="Nord"] .skill-md input[type="checkbox"] { - accent-color: #88c0d0; -} diff --git a/src/workspaces/themes/Nord/variables.css b/src/workspaces/themes/Nord/variables.css deleted file mode 100644 index 430ec2a2..00000000 --- a/src/workspaces/themes/Nord/variables.css +++ /dev/null @@ -1,92 +0,0 @@ -@layer base { - [data-color-theme="Nord"] { - /* Brand colors */ - --duck-yellow: #ebcb8b; - --duck-orange: #d08770; - --duck-teal: #88c0d0; - --duck-forest: #d8dee9; - --duck-dark: #eceff4; - --duck-beige: #3b4252; - - /* Page background */ - --pixel-grid-color: rgba(136, 192, 208, 0.06); - - /* Glass surfaces */ - --glass-bg: rgba(0, 0, 0, 0.25); - --glass-border: rgba(136, 192, 208, 0.12); - --dock-bg: rgba(0, 0, 0, 0.35); - --dock-border: rgba(136, 192, 208, 0.08); - --dock-tooltip-bg: rgba(0, 0, 0, 0.9); - - /* Card component */ - --card-bg: rgba(59, 66, 82, 0.92); - --card-grid-color: rgba(136, 192, 208, 0.04); - - --cta: 193.3 43.4% 67.5%; - --cta-foreground: 220 16.4% 21.6%; - - --naturegreen: 178.7 25.1% 64.9%; - --naturegreen-foreground: 220 16.4% 21.6%; - - --background: 220 16.4% 21.6%; - --foreground: 217.5 26.7% 94.1%; - - --card: 221.7 16.3% 27.6%; - --card-foreground: 217.5 26.7% 94.1%; - - --popover: 221.7 16.3% 27.6%; - --popover-foreground: 217.5 26.7% 94.1%; - - --primary: 193.3 43.4% 67.5%; - --primary-foreground: 220 16.4% 21.6%; - - --secondary: 220 16.8% 31.6%; - --secondary-foreground: 217.5 26.7% 94.1%; - - --muted: 221.7 16.3% 27.6%; - --muted-foreground: 218.8 27.9% 88%; - - --accent: 178.7 25.1% 64.9%; - --accent-foreground: 220 16.4% 21.6%; - - --destructive: 354.3 42.3% 56.5%; - --destructive-foreground: 217.5 26.7% 94.1%; - - --success: 92.4 27.8% 64.7%; - --success-foreground: 220 16.4% 21.6%; - - --brand: 193.3 43.4% 67.5%; - --brand-foreground: 220 16.4% 21.6%; - --brand-muted: 221.7 16.3% 27.6%; - - --warning: 40 70.6% 73.3%; - --warning-foreground: 220 16.4% 21.6%; - - --border: 220 16.8% 31.6%; - --input: 220 16.8% 31.6%; - --ring: 193.3 43.4% 67.5%; - - --radius: 0.5rem; - - /* Chart gradients */ - --chart-primary: 193.3 43.4% 67.5%; - --chart-secondary: 40 70.6% 73.3%; - - /* Status colors */ - --status-success: 92.4 27.8% 64.7%; - --status-warning: 40 70.6% 73.3%; - --status-in-progress: 193.3 43.4% 67.5%; - - --sidebar-background: 221.7 16.3% 27.6%; - --sidebar-foreground: 218.8 27.9% 88%; - --sidebar-primary: 193.3 43.4% 67.5%; - --sidebar-primary-foreground: 220 16.4% 21.6%; - --sidebar-accent: 220 16.8% 31.6%; - --sidebar-accent-foreground: 217.5 26.7% 94.1%; - --sidebar-border: 220 16.5% 35.7%; - --sidebar-ring: 193.3 43.4% 67.5%; - - /* Hover Effect */ - --ctahover: 178.7 25.1% 64.9%; - } -} diff --git a/src/workspaces/themes/OsakaJade/client.ts b/src/workspaces/themes/OsakaJade/client.ts deleted file mode 100644 index a0bea0e6..00000000 --- a/src/workspaces/themes/OsakaJade/client.ts +++ /dev/null @@ -1,2 +0,0 @@ -import './variables.css'; -import './prose.css'; diff --git a/src/workspaces/themes/OsakaJade/index.ts b/src/workspaces/themes/OsakaJade/index.ts deleted file mode 100644 index bff47123..00000000 --- a/src/workspaces/themes/OsakaJade/index.ts +++ /dev/null @@ -1 +0,0 @@ -export const meta = { id: 'OsakaJade', name: 'Osaka Jade', description: 'Electric jade and neon cyan on a midnight canvas.' }; diff --git a/src/workspaces/themes/OsakaJade/prose.css b/src/workspaces/themes/OsakaJade/prose.css deleted file mode 100644 index 3c66d7a2..00000000 --- a/src/workspaces/themes/OsakaJade/prose.css +++ /dev/null @@ -1,124 +0,0 @@ -/* File Viewer — Markdown Prose */ -[data-color-theme="OsakaJade"] .file-viewer-md { - color: #c5cdd9; -} - -[data-color-theme="OsakaJade"] .file-viewer-md h1 { - border-bottom-color: rgba(41, 46, 66, 0.4); -} - -[data-color-theme="OsakaJade"] .file-viewer-md h2 { - border-bottom-color: rgba(41, 46, 66, 0.3); -} - -[data-color-theme="OsakaJade"] .file-viewer-md a { - color: #2ac3de; -} - -[data-color-theme="OsakaJade"] .file-viewer-md a:hover { - color: #0db9d7; -} - -[data-color-theme="OsakaJade"] .file-viewer-md strong { - color: #c5cdd9; -} - -[data-color-theme="OsakaJade"] .file-viewer-md blockquote { - border-left-color: #2ac3de; - background: rgba(42, 195, 222, 0.06); - color: #565f89; -} - -[data-color-theme="OsakaJade"] .file-viewer-md li::marker { - color: #2ac3de; -} - -[data-color-theme="OsakaJade"] .file-viewer-md hr { - background: rgba(41, 46, 66, 0.4); -} - -[data-color-theme="OsakaJade"] .file-viewer-md th { - background: rgba(42, 195, 222, 0.08); - border-color: rgba(41, 46, 66, 0.4); -} - -[data-color-theme="OsakaJade"] .file-viewer-md td { - border-color: rgba(41, 46, 66, 0.3); -} - -[data-color-theme="OsakaJade"] .file-viewer-md tr:nth-child(even) { - background: rgba(41, 46, 66, 0.1); -} - -[data-color-theme="OsakaJade"] .file-viewer-md input[type="checkbox"] { - accent-color: #2ac3de; -} - -/* Skills — Markdown Prose */ -[data-color-theme="OsakaJade"] .skill-md { - color: #c5cdd9; -} - -[data-color-theme="OsakaJade"] .skill-md h1 { - border-bottom-color: rgba(41, 46, 66, 0.4); -} - -[data-color-theme="OsakaJade"] .skill-md h2 { - border-bottom-color: rgba(41, 46, 66, 0.3); -} - -[data-color-theme="OsakaJade"] .skill-md a { - color: #2ac3de; -} - -[data-color-theme="OsakaJade"] .skill-md a:hover { - color: #0db9d7; -} - -[data-color-theme="OsakaJade"] .skill-md strong { - color: #c5cdd9; -} - -[data-color-theme="OsakaJade"] .skill-md blockquote { - border-left-color: #2ac3de; - background: rgba(42, 195, 222, 0.06); - color: #565f89; -} - -[data-color-theme="OsakaJade"] .skill-md li::marker { - color: #2ac3de; -} - -[data-color-theme="OsakaJade"] .skill-md code { - background: rgba(42, 195, 222, 0.1); - color: #2ac3de; -} - -[data-color-theme="OsakaJade"] .skill-md pre { - background: #16161e; -} - -[data-color-theme="OsakaJade"] .skill-md pre code { - color: #c5cdd9; -} - -[data-color-theme="OsakaJade"] .skill-md hr { - background: rgba(41, 46, 66, 0.4); -} - -[data-color-theme="OsakaJade"] .skill-md th { - background: rgba(42, 195, 222, 0.08); - border-color: rgba(41, 46, 66, 0.4); -} - -[data-color-theme="OsakaJade"] .skill-md td { - border-color: rgba(41, 46, 66, 0.3); -} - -[data-color-theme="OsakaJade"] .skill-md tr:nth-child(even) { - background: rgba(41, 46, 66, 0.1); -} - -[data-color-theme="OsakaJade"] .skill-md input[type="checkbox"] { - accent-color: #2ac3de; -} diff --git a/src/workspaces/themes/OsakaJade/variables.css b/src/workspaces/themes/OsakaJade/variables.css deleted file mode 100644 index 3e327911..00000000 --- a/src/workspaces/themes/OsakaJade/variables.css +++ /dev/null @@ -1,92 +0,0 @@ -@layer base { - [data-color-theme="OsakaJade"] { - /* Brand colors */ - --duck-yellow: #e0af68; - --duck-orange: #f7768e; - --duck-teal: #2ac3de; - --duck-forest: #565f89; - --duck-dark: #c5cdd9; - --duck-beige: #1f2335; - - /* Page background */ - --pixel-grid-color: rgba(42, 195, 222, 0.06); - - /* Glass surfaces */ - --glass-bg: rgba(0, 0, 0, 0.25); - --glass-border: rgba(42, 195, 222, 0.12); - --dock-bg: rgba(0, 0, 0, 0.35); - --dock-border: rgba(42, 195, 222, 0.08); - --dock-tooltip-bg: rgba(0, 0, 0, 0.9); - - /* Card component */ - --card-bg: rgba(22, 22, 30, 0.92); - --card-grid-color: rgba(42, 195, 222, 0.04); - - --cta: 189 73.2% 51.8%; - --cta-foreground: 235 18.8% 12.5%; - - --naturegreen: 188.9 88.6% 44.7%; - --naturegreen-foreground: 235 18.8% 12.5%; - - --background: 235 18.8% 12.5%; - --foreground: 216 20.8% 81.2%; - - --card: 240 15.4% 10.2%; - --card-foreground: 216 20.8% 81.2%; - - --popover: 240 15.4% 10.2%; - --popover-foreground: 216 20.8% 81.2%; - - --primary: 189 73.2% 51.8%; - --primary-foreground: 235 18.8% 12.5%; - - --secondary: 228 23.4% 21%; - --secondary-foreground: 216 20.8% 81.2%; - - --muted: 229.1 26.2% 16.5%; - --muted-foreground: 229.4 22.9% 43.7%; - - --accent: 188.9 88.6% 44.7%; - --accent-foreground: 235 18.8% 12.5%; - - --destructive: 348.8 89% 71.6%; - --destructive-foreground: 216 20.8% 81.2%; - - --success: 88.8 50.5% 61.2%; - --success-foreground: 235 18.8% 12.5%; - - --brand: 189 73.2% 51.8%; - --brand-foreground: 235 18.8% 12.5%; - --brand-muted: 229.1 26.2% 16.5%; - - --warning: 35.5 65.9% 64.3%; - --warning-foreground: 235 18.8% 12.5%; - - --border: 228 23.4% 21%; - --input: 228 23.4% 21%; - --ring: 189 73.2% 51.8%; - - --radius: 0.5rem; - - /* Chart gradients */ - --chart-primary: 189 73.2% 51.8%; - --chart-secondary: 35.5 65.9% 64.3%; - - /* Status colors */ - --status-success: 88.8 50.5% 61.2%; - --status-warning: 35.5 65.9% 64.3%; - --status-in-progress: 189 73.2% 51.8%; - - --sidebar-background: 240 15.4% 10.2%; - --sidebar-foreground: 229.4 22.9% 43.7%; - --sidebar-primary: 189 73.2% 51.8%; - --sidebar-primary-foreground: 235 18.8% 12.5%; - --sidebar-accent: 229.1 26.2% 16.5%; - --sidebar-accent-foreground: 216 20.8% 81.2%; - --sidebar-border: 228 23.4% 21%; - --sidebar-ring: 189 73.2% 51.8%; - - /* Hover Effect */ - --ctahover: 188.9 88.6% 44.7%; - } -} diff --git a/src/workspaces/themes/Ristretto/client.ts b/src/workspaces/themes/Ristretto/client.ts deleted file mode 100644 index a0bea0e6..00000000 --- a/src/workspaces/themes/Ristretto/client.ts +++ /dev/null @@ -1,2 +0,0 @@ -import './variables.css'; -import './prose.css'; diff --git a/src/workspaces/themes/Ristretto/index.ts b/src/workspaces/themes/Ristretto/index.ts deleted file mode 100644 index 396948c7..00000000 --- a/src/workspaces/themes/Ristretto/index.ts +++ /dev/null @@ -1 +0,0 @@ -export const meta = { id: 'Ristretto', name: 'Ristretto', description: 'Warm coffee tones with amber and burnt orange.' }; diff --git a/src/workspaces/themes/Ristretto/prose.css b/src/workspaces/themes/Ristretto/prose.css deleted file mode 100644 index 1c572188..00000000 --- a/src/workspaces/themes/Ristretto/prose.css +++ /dev/null @@ -1,124 +0,0 @@ -/* File Viewer — Markdown Prose */ -[data-color-theme="Ristretto"] .file-viewer-md { - color: #ebe5df; -} - -[data-color-theme="Ristretto"] .file-viewer-md h1 { - border-bottom-color: rgba(95, 87, 79, 0.4); -} - -[data-color-theme="Ristretto"] .file-viewer-md h2 { - border-bottom-color: rgba(95, 87, 79, 0.3); -} - -[data-color-theme="Ristretto"] .file-viewer-md a { - color: #fc9867; -} - -[data-color-theme="Ristretto"] .file-viewer-md a:hover { - color: #fbb360; -} - -[data-color-theme="Ristretto"] .file-viewer-md strong { - color: #ebe5df; -} - -[data-color-theme="Ristretto"] .file-viewer-md blockquote { - border-left-color: #fc9867; - background: rgba(252, 152, 103, 0.06); - color: #ada49d; -} - -[data-color-theme="Ristretto"] .file-viewer-md li::marker { - color: #fc9867; -} - -[data-color-theme="Ristretto"] .file-viewer-md hr { - background: rgba(95, 87, 79, 0.4); -} - -[data-color-theme="Ristretto"] .file-viewer-md th { - background: rgba(252, 152, 103, 0.08); - border-color: rgba(95, 87, 79, 0.4); -} - -[data-color-theme="Ristretto"] .file-viewer-md td { - border-color: rgba(95, 87, 79, 0.3); -} - -[data-color-theme="Ristretto"] .file-viewer-md tr:nth-child(even) { - background: rgba(95, 87, 79, 0.1); -} - -[data-color-theme="Ristretto"] .file-viewer-md input[type="checkbox"] { - accent-color: #fc9867; -} - -/* Skills — Markdown Prose */ -[data-color-theme="Ristretto"] .skill-md { - color: #ebe5df; -} - -[data-color-theme="Ristretto"] .skill-md h1 { - border-bottom-color: rgba(95, 87, 79, 0.4); -} - -[data-color-theme="Ristretto"] .skill-md h2 { - border-bottom-color: rgba(95, 87, 79, 0.3); -} - -[data-color-theme="Ristretto"] .skill-md a { - color: #fc9867; -} - -[data-color-theme="Ristretto"] .skill-md a:hover { - color: #fbb360; -} - -[data-color-theme="Ristretto"] .skill-md strong { - color: #ebe5df; -} - -[data-color-theme="Ristretto"] .skill-md blockquote { - border-left-color: #fc9867; - background: rgba(252, 152, 103, 0.06); - color: #ada49d; -} - -[data-color-theme="Ristretto"] .skill-md li::marker { - color: #fc9867; -} - -[data-color-theme="Ristretto"] .skill-md code { - background: rgba(252, 152, 103, 0.1); - color: #fc9867; -} - -[data-color-theme="Ristretto"] .skill-md pre { - background: #352f2a; -} - -[data-color-theme="Ristretto"] .skill-md pre code { - color: #ebe5df; -} - -[data-color-theme="Ristretto"] .skill-md hr { - background: rgba(95, 87, 79, 0.4); -} - -[data-color-theme="Ristretto"] .skill-md th { - background: rgba(252, 152, 103, 0.08); - border-color: rgba(95, 87, 79, 0.4); -} - -[data-color-theme="Ristretto"] .skill-md td { - border-color: rgba(95, 87, 79, 0.3); -} - -[data-color-theme="Ristretto"] .skill-md tr:nth-child(even) { - background: rgba(95, 87, 79, 0.1); -} - -[data-color-theme="Ristretto"] .skill-md input[type="checkbox"] { - accent-color: #fc9867; -} diff --git a/src/workspaces/themes/Ristretto/variables.css b/src/workspaces/themes/Ristretto/variables.css deleted file mode 100644 index 1e01f9de..00000000 --- a/src/workspaces/themes/Ristretto/variables.css +++ /dev/null @@ -1,92 +0,0 @@ -@layer base { - [data-color-theme="Ristretto"] { - /* Brand colors */ - --duck-yellow: #fbb360; - --duck-orange: #fc9867; - --duck-teal: #fc9867; - --duck-forest: #ada49d; - --duck-dark: #ebe5df; - --duck-beige: #4d4743; - - /* Page background */ - --pixel-grid-color: rgba(252, 152, 103, 0.06); - - /* Glass surfaces */ - --glass-bg: rgba(0, 0, 0, 0.25); - --glass-border: rgba(252, 152, 103, 0.12); - --dock-bg: rgba(0, 0, 0, 0.35); - --dock-border: rgba(252, 152, 103, 0.08); - --dock-tooltip-bg: rgba(0, 0, 0, 0.9); - - /* Card component */ - --card-bg: rgba(53, 47, 42, 0.92); - --card-grid-color: rgba(252, 152, 103, 0.04); - - --cta: 19.7 96.1% 69.6%; - --cta-foreground: 34.3 5.8% 23.7%; - - --naturegreen: 32.1 95.1% 68%; - --naturegreen-foreground: 34.3 5.8% 23.7%; - - --background: 34.3 5.8% 23.7%; - --foreground: 30 23.1% 89.8%; - - --card: 27.3 11.6% 18.6%; - --card-foreground: 30 23.1% 89.8%; - - --popover: 27.3 11.6% 18.6%; - --popover-foreground: 30 23.1% 89.8%; - - --primary: 19.7 96.1% 69.6%; - --primary-foreground: 34.3 5.8% 23.7%; - - --secondary: 30 9.2% 34.1%; - --secondary-foreground: 30 23.1% 89.8%; - - --muted: 24 6.9% 28.2%; - --muted-foreground: 26.3 8.9% 64.7%; - - --accent: 32.1 95.1% 68%; - --accent-foreground: 34.3 5.8% 23.7%; - - --destructive: 0 57.2% 63.3%; - --destructive-foreground: 30 23.1% 89.8%; - - --success: 113.6 13.5% 59.2%; - --success-foreground: 34.3 5.8% 23.7%; - - --brand: 19.7 96.1% 69.6%; - --brand-foreground: 34.3 5.8% 23.7%; - --brand-muted: 24 6.9% 28.2%; - - --warning: 32.1 95.1% 68%; - --warning-foreground: 34.3 5.8% 23.7%; - - --border: 30 9.2% 34.1%; - --input: 30 9.2% 34.1%; - --ring: 19.7 96.1% 69.6%; - - --radius: 0.5rem; - - /* Chart gradients */ - --chart-primary: 19.7 96.1% 69.6%; - --chart-secondary: 32.1 95.1% 68%; - - /* Status colors */ - --status-success: 113.6 13.5% 59.2%; - --status-warning: 32.1 95.1% 68%; - --status-in-progress: 19.7 96.1% 69.6%; - - --sidebar-background: 27.3 11.6% 18.6%; - --sidebar-foreground: 26.3 8.9% 64.7%; - --sidebar-primary: 19.7 96.1% 69.6%; - --sidebar-primary-foreground: 34.3 5.8% 23.7%; - --sidebar-accent: 24 6.9% 28.2%; - --sidebar-accent-foreground: 30 23.1% 89.8%; - --sidebar-border: 30 9.2% 34.1%; - --sidebar-ring: 19.7 96.1% 69.6%; - - /* Hover Effect */ - --ctahover: 32.1 95.1% 68%; - } -} diff --git a/src/workspaces/themes/RosePine/client.ts b/src/workspaces/themes/RosePine/client.ts deleted file mode 100644 index a0bea0e6..00000000 --- a/src/workspaces/themes/RosePine/client.ts +++ /dev/null @@ -1,2 +0,0 @@ -import './variables.css'; -import './prose.css'; diff --git a/src/workspaces/themes/RosePine/index.ts b/src/workspaces/themes/RosePine/index.ts deleted file mode 100644 index b9c129e4..00000000 --- a/src/workspaces/themes/RosePine/index.ts +++ /dev/null @@ -1 +0,0 @@ -export const meta = { id: 'RosePine', name: 'Rose Pine', description: 'Romantic purples and dusty rose on a moonlit base.' }; diff --git a/src/workspaces/themes/RosePine/prose.css b/src/workspaces/themes/RosePine/prose.css deleted file mode 100644 index d64a14ce..00000000 --- a/src/workspaces/themes/RosePine/prose.css +++ /dev/null @@ -1,124 +0,0 @@ -/* File Viewer — Markdown Prose */ -[data-color-theme="RosePine"] .file-viewer-md { - color: #e0def4; -} - -[data-color-theme="RosePine"] .file-viewer-md h1 { - border-bottom-color: rgba(38, 35, 58, 0.4); -} - -[data-color-theme="RosePine"] .file-viewer-md h2 { - border-bottom-color: rgba(38, 35, 58, 0.3); -} - -[data-color-theme="RosePine"] .file-viewer-md a { - color: #c4a7e7; -} - -[data-color-theme="RosePine"] .file-viewer-md a:hover { - color: #ebbcba; -} - -[data-color-theme="RosePine"] .file-viewer-md strong { - color: #e0def4; -} - -[data-color-theme="RosePine"] .file-viewer-md blockquote { - border-left-color: #c4a7e7; - background: rgba(196, 167, 231, 0.06); - color: #908caa; -} - -[data-color-theme="RosePine"] .file-viewer-md li::marker { - color: #c4a7e7; -} - -[data-color-theme="RosePine"] .file-viewer-md hr { - background: rgba(38, 35, 58, 0.4); -} - -[data-color-theme="RosePine"] .file-viewer-md th { - background: rgba(196, 167, 231, 0.08); - border-color: rgba(38, 35, 58, 0.4); -} - -[data-color-theme="RosePine"] .file-viewer-md td { - border-color: rgba(38, 35, 58, 0.3); -} - -[data-color-theme="RosePine"] .file-viewer-md tr:nth-child(even) { - background: rgba(38, 35, 58, 0.1); -} - -[data-color-theme="RosePine"] .file-viewer-md input[type="checkbox"] { - accent-color: #c4a7e7; -} - -/* Skills — Markdown Prose */ -[data-color-theme="RosePine"] .skill-md { - color: #e0def4; -} - -[data-color-theme="RosePine"] .skill-md h1 { - border-bottom-color: rgba(38, 35, 58, 0.4); -} - -[data-color-theme="RosePine"] .skill-md h2 { - border-bottom-color: rgba(38, 35, 58, 0.3); -} - -[data-color-theme="RosePine"] .skill-md a { - color: #c4a7e7; -} - -[data-color-theme="RosePine"] .skill-md a:hover { - color: #ebbcba; -} - -[data-color-theme="RosePine"] .skill-md strong { - color: #e0def4; -} - -[data-color-theme="RosePine"] .skill-md blockquote { - border-left-color: #c4a7e7; - background: rgba(196, 167, 231, 0.06); - color: #908caa; -} - -[data-color-theme="RosePine"] .skill-md li::marker { - color: #c4a7e7; -} - -[data-color-theme="RosePine"] .skill-md code { - background: rgba(196, 167, 231, 0.1); - color: #c4a7e7; -} - -[data-color-theme="RosePine"] .skill-md pre { - background: #1f1d2e; -} - -[data-color-theme="RosePine"] .skill-md pre code { - color: #e0def4; -} - -[data-color-theme="RosePine"] .skill-md hr { - background: rgba(38, 35, 58, 0.4); -} - -[data-color-theme="RosePine"] .skill-md th { - background: rgba(196, 167, 231, 0.08); - border-color: rgba(38, 35, 58, 0.4); -} - -[data-color-theme="RosePine"] .skill-md td { - border-color: rgba(38, 35, 58, 0.3); -} - -[data-color-theme="RosePine"] .skill-md tr:nth-child(even) { - background: rgba(38, 35, 58, 0.1); -} - -[data-color-theme="RosePine"] .skill-md input[type="checkbox"] { - accent-color: #c4a7e7; -} diff --git a/src/workspaces/themes/RosePine/variables.css b/src/workspaces/themes/RosePine/variables.css deleted file mode 100644 index 1bd30dd6..00000000 --- a/src/workspaces/themes/RosePine/variables.css +++ /dev/null @@ -1,92 +0,0 @@ -@layer base { - [data-color-theme="RosePine"] { - /* Brand colors */ - --duck-yellow: #f6c177; - --duck-orange: #eb6f92; - --duck-teal: #c4a7e7; - --duck-forest: #908caa; - --duck-dark: #e0def4; - --duck-beige: #26233a; - - /* Page background */ - --pixel-grid-color: rgba(196, 167, 231, 0.06); - - /* Glass surfaces */ - --glass-bg: rgba(0, 0, 0, 0.25); - --glass-border: rgba(196, 167, 231, 0.12); - --dock-bg: rgba(0, 0, 0, 0.35); - --dock-border: rgba(196, 167, 231, 0.08); - --dock-tooltip-bg: rgba(0, 0, 0, 0.9); - - /* Card component */ - --card-bg: rgba(31, 29, 46, 0.92); - --card-grid-color: rgba(196, 167, 231, 0.04); - - --cta: 267.2 57.1% 78%; - --cta-foreground: 249.2 22% 11.6%; - - --naturegreen: 2.4 55.1% 82.5%; - --naturegreen-foreground: 249.2 22% 11.6%; - - --background: 249.2 22% 11.6%; - --foreground: 245.5 50% 91.4%; - - --card: 247.1 22.7% 14.7%; - --card-foreground: 245.5 50% 91.4%; - - --popover: 247.1 22.7% 14.7%; - --popover-foreground: 245.5 50% 91.4%; - - --primary: 267.2 57.1% 78%; - --primary-foreground: 249.2 22% 11.6%; - - --secondary: 247.8 24.7% 18.2%; - --secondary-foreground: 245.5 50% 91.4%; - - --muted: 247.8 24.7% 18.2%; - --muted-foreground: 248 15% 60.8%; - - --accent: 2.4 55.1% 82.5%; - --accent-foreground: 249.2 22% 11.6%; - - --destructive: 343.1 75.6% 67.8%; - --destructive-foreground: 245.5 50% 91.4%; - - --success: 189 43.5% 72.9%; - --success-foreground: 249.2 22% 11.6%; - - --brand: 267.2 57.1% 78%; - --brand-foreground: 249.2 22% 11.6%; - --brand-muted: 247.8 24.7% 18.2%; - - --warning: 35 87.6% 71.6%; - --warning-foreground: 249.2 22% 11.6%; - - --border: 247.8 24.7% 18.2%; - --input: 247.8 24.7% 18.2%; - --ring: 267.2 57.1% 78%; - - --radius: 0.5rem; - - /* Chart gradients */ - --chart-primary: 267.2 57.1% 78%; - --chart-secondary: 35 87.6% 71.6%; - - /* Status colors */ - --status-success: 189 43.5% 72.9%; - --status-warning: 35 87.6% 71.6%; - --status-in-progress: 267.2 57.1% 78%; - - --sidebar-background: 247.1 22.7% 14.7%; - --sidebar-foreground: 248 15% 60.8%; - --sidebar-primary: 267.2 57.1% 78%; - --sidebar-primary-foreground: 249.2 22% 11.6%; - --sidebar-accent: 247.8 24.7% 18.2%; - --sidebar-accent-foreground: 245.5 50% 91.4%; - --sidebar-border: 248.6 14.7% 28%; - --sidebar-ring: 267.2 57.1% 78%; - - /* Hover Effect */ - --ctahover: 2.4 55.1% 82.5%; - } -} diff --git a/src/workspaces/themes/TokyoNight/client.ts b/src/workspaces/themes/TokyoNight/client.ts deleted file mode 100644 index a0bea0e6..00000000 --- a/src/workspaces/themes/TokyoNight/client.ts +++ /dev/null @@ -1,2 +0,0 @@ -import './variables.css'; -import './prose.css'; diff --git a/src/workspaces/themes/TokyoNight/index.ts b/src/workspaces/themes/TokyoNight/index.ts deleted file mode 100644 index 6d99f07c..00000000 --- a/src/workspaces/themes/TokyoNight/index.ts +++ /dev/null @@ -1 +0,0 @@ -export const meta = { id: 'TokyoNight', name: 'Tokyo Night', description: 'Moonlight blues and soft purples from a Tokyo evening.' }; diff --git a/src/workspaces/themes/TokyoNight/prose.css b/src/workspaces/themes/TokyoNight/prose.css deleted file mode 100644 index bd0ef7e3..00000000 --- a/src/workspaces/themes/TokyoNight/prose.css +++ /dev/null @@ -1,124 +0,0 @@ -/* File Viewer — Markdown Prose */ -[data-color-theme="TokyoNight"] .file-viewer-md { - color: #c8d3f5; -} - -[data-color-theme="TokyoNight"] .file-viewer-md h1 { - border-bottom-color: rgba(59, 66, 97, 0.4); -} - -[data-color-theme="TokyoNight"] .file-viewer-md h2 { - border-bottom-color: rgba(59, 66, 97, 0.3); -} - -[data-color-theme="TokyoNight"] .file-viewer-md a { - color: #82aaff; -} - -[data-color-theme="TokyoNight"] .file-viewer-md a:hover { - color: #86e1fc; -} - -[data-color-theme="TokyoNight"] .file-viewer-md strong { - color: #c8d3f5; -} - -[data-color-theme="TokyoNight"] .file-viewer-md blockquote { - border-left-color: #82aaff; - background: rgba(130, 170, 255, 0.06); - color: #828bb8; -} - -[data-color-theme="TokyoNight"] .file-viewer-md li::marker { - color: #82aaff; -} - -[data-color-theme="TokyoNight"] .file-viewer-md hr { - background: rgba(59, 66, 97, 0.4); -} - -[data-color-theme="TokyoNight"] .file-viewer-md th { - background: rgba(130, 170, 255, 0.08); - border-color: rgba(59, 66, 97, 0.4); -} - -[data-color-theme="TokyoNight"] .file-viewer-md td { - border-color: rgba(59, 66, 97, 0.3); -} - -[data-color-theme="TokyoNight"] .file-viewer-md tr:nth-child(even) { - background: rgba(59, 66, 97, 0.1); -} - -[data-color-theme="TokyoNight"] .file-viewer-md input[type="checkbox"] { - accent-color: #82aaff; -} - -/* Skills — Markdown Prose */ -[data-color-theme="TokyoNight"] .skill-md { - color: #c8d3f5; -} - -[data-color-theme="TokyoNight"] .skill-md h1 { - border-bottom-color: rgba(59, 66, 97, 0.4); -} - -[data-color-theme="TokyoNight"] .skill-md h2 { - border-bottom-color: rgba(59, 66, 97, 0.3); -} - -[data-color-theme="TokyoNight"] .skill-md a { - color: #82aaff; -} - -[data-color-theme="TokyoNight"] .skill-md a:hover { - color: #86e1fc; -} - -[data-color-theme="TokyoNight"] .skill-md strong { - color: #c8d3f5; -} - -[data-color-theme="TokyoNight"] .skill-md blockquote { - border-left-color: #82aaff; - background: rgba(130, 170, 255, 0.06); - color: #828bb8; -} - -[data-color-theme="TokyoNight"] .skill-md li::marker { - color: #82aaff; -} - -[data-color-theme="TokyoNight"] .skill-md code { - background: rgba(130, 170, 255, 0.1); - color: #82aaff; -} - -[data-color-theme="TokyoNight"] .skill-md pre { - background: #1e2030; -} - -[data-color-theme="TokyoNight"] .skill-md pre code { - color: #c8d3f5; -} - -[data-color-theme="TokyoNight"] .skill-md hr { - background: rgba(59, 66, 97, 0.4); -} - -[data-color-theme="TokyoNight"] .skill-md th { - background: rgba(130, 170, 255, 0.08); - border-color: rgba(59, 66, 97, 0.4); -} - -[data-color-theme="TokyoNight"] .skill-md td { - border-color: rgba(59, 66, 97, 0.3); -} - -[data-color-theme="TokyoNight"] .skill-md tr:nth-child(even) { - background: rgba(59, 66, 97, 0.1); -} - -[data-color-theme="TokyoNight"] .skill-md input[type="checkbox"] { - accent-color: #82aaff; -} diff --git a/src/workspaces/themes/TokyoNight/variables.css b/src/workspaces/themes/TokyoNight/variables.css deleted file mode 100644 index 751d2884..00000000 --- a/src/workspaces/themes/TokyoNight/variables.css +++ /dev/null @@ -1,92 +0,0 @@ -@layer base { - [data-color-theme="TokyoNight"] { - /* Brand colors */ - --duck-yellow: #ffc777; - --duck-orange: #ff966c; - --duck-teal: #82aaff; - --duck-forest: #828bb8; - --duck-dark: #c8d3f5; - --duck-beige: #2f334d; - - /* Page background */ - --pixel-grid-color: rgba(130, 170, 255, 0.06); - - /* Glass surfaces */ - --glass-bg: rgba(0, 0, 0, 0.25); - --glass-border: rgba(130, 170, 255, 0.12); - --dock-bg: rgba(0, 0, 0, 0.35); - --dock-border: rgba(130, 170, 255, 0.08); - --dock-tooltip-bg: rgba(0, 0, 0, 0.9); - - /* Card component */ - --card-bg: rgba(30, 32, 48, 0.92); - --card-grid-color: rgba(130, 170, 255, 0.04); - - --cta: 220.8 100% 75.5%; - --cta-foreground: 232.5 22.9% 13.7%; - - --naturegreen: 193.7 95.2% 75.7%; - --naturegreen-foreground: 232.5 22.9% 13.7%; - - --background: 234 22.7% 17.3%; - --foreground: 225.3 69.2% 87.3%; - - --card: 233.3 23.1% 15.3%; - --card-foreground: 225.3 69.2% 87.3%; - - --popover: 233.3 23.1% 15.3%; - --popover-foreground: 225.3 69.2% 87.3%; - - --primary: 220.8 100% 75.5%; - --primary-foreground: 232.5 22.9% 13.7%; - - --secondary: 228.9 24.4% 30.6%; - --secondary-foreground: 225.3 69.2% 87.3%; - - --muted: 232 24.2% 24.3%; - --muted-foreground: 230 27.6% 61.6%; - - --accent: 193.7 95.2% 75.7%; - --accent-foreground: 232.5 22.9% 13.7%; - - --destructive: 349.6 54.3% 50.2%; - --destructive-foreground: 225.3 69.2% 87.3%; - - --success: 84.4 66.4% 73.1%; - --success-foreground: 232.5 22.9% 13.7%; - - --brand: 220.8 100% 75.5%; - --brand-foreground: 232.5 22.9% 13.7%; - --brand-muted: 232 24.2% 24.3%; - - --warning: 35.3 100% 73.3%; - --warning-foreground: 234 22.7% 17.3%; - - --border: 228.9 24.4% 30.6%; - --input: 228.9 24.4% 30.6%; - --ring: 220.8 100% 75.5%; - - --radius: 0.5rem; - - /* Chart gradients */ - --chart-primary: 220.8 100% 75.5%; - --chart-secondary: 35.3 100% 73.3%; - - /* Status colors */ - --status-success: 84.4 66.4% 73.1%; - --status-warning: 35.3 100% 73.3%; - --status-in-progress: 220.8 100% 75.5%; - - --sidebar-background: 233.3 23.1% 15.3%; - --sidebar-foreground: 230 27.6% 61.6%; - --sidebar-primary: 220.8 100% 75.5%; - --sidebar-primary-foreground: 232.5 22.9% 13.7%; - --sidebar-accent: 232 24.2% 24.3%; - --sidebar-accent-foreground: 225.3 69.2% 87.3%; - --sidebar-border: 228.9 24.4% 30.6%; - --sidebar-ring: 220.8 100% 75.5%; - - /* Hover Effect */ - --ctahover: 193.7 95.2% 75.7%; - } -} diff --git a/src/workspaces/themes/index.ts b/src/workspaces/themes/index.ts deleted file mode 100644 index 36e127a7..00000000 --- a/src/workspaces/themes/index.ts +++ /dev/null @@ -1,14 +0,0 @@ -export const themes = [ - { id: 'DuckPond', name: 'Duck Pond' }, - { id: 'TokyoNight', name: 'Tokyo Night' }, - { id: 'CatppuccinLatte', name: 'Catppuccin Latte' }, - { id: 'CatppuccinMocha', name: 'Catppuccin Mocha' }, - { id: 'Everforest', name: 'Everforest' }, - { id: 'Gruvbox', name: 'Gruvbox' }, - { id: 'Kanagawa', name: 'Kanagawa' }, - { id: 'MatteBlack', name: 'Matte Black' }, - { id: 'Nord', name: 'Nord' }, - { id: 'OsakaJade', name: 'Osaka Jade' }, - { id: 'Ristretto', name: 'Ristretto' }, - { id: 'RosePine', name: 'Rose Pine' }, -] as const; diff --git a/src/workspaces/themes/package.json b/src/workspaces/themes/package.json deleted file mode 100644 index e4d4f63a..00000000 --- a/src/workspaces/themes/package.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "name": "themes", - "private": true, - "exports": { - ".": "./index.ts", - "./DuckPond": "./DuckPond/index.ts", - "./DuckPond/client": "./DuckPond/client.ts", - "./TokyoNight": "./TokyoNight/index.ts", - "./TokyoNight/client": "./TokyoNight/client.ts", - "./CatppuccinLatte": "./CatppuccinLatte/index.ts", - "./CatppuccinLatte/client": "./CatppuccinLatte/client.ts", - "./CatppuccinMocha": "./CatppuccinMocha/index.ts", - "./CatppuccinMocha/client": "./CatppuccinMocha/client.ts", - "./Everforest": "./Everforest/index.ts", - "./Everforest/client": "./Everforest/client.ts", - "./Gruvbox": "./Gruvbox/index.ts", - "./Gruvbox/client": "./Gruvbox/client.ts", - "./Kanagawa": "./Kanagawa/index.ts", - "./Kanagawa/client": "./Kanagawa/client.ts", - "./MatteBlack": "./MatteBlack/index.ts", - "./MatteBlack/client": "./MatteBlack/client.ts", - "./Nord": "./Nord/index.ts", - "./Nord/client": "./Nord/client.ts", - "./OsakaJade": "./OsakaJade/index.ts", - "./OsakaJade/client": "./OsakaJade/client.ts", - "./Ristretto": "./Ristretto/index.ts", - "./Ristretto/client": "./Ristretto/client.ts", - "./RosePine": "./RosePine/index.ts", - "./RosePine/client": "./RosePine/client.ts" - } -} diff --git a/src/workspaces/plugins/Terminal/client/TerminalView.tsx b/src/workspaces/widgets/TerminalView.tsx similarity index 100% rename from src/workspaces/plugins/Terminal/client/TerminalView.tsx rename to src/workspaces/widgets/TerminalView.tsx diff --git a/src/workspaces/widgets/package.json b/src/workspaces/widgets/package.json new file mode 100644 index 00000000..0dbeba53 --- /dev/null +++ b/src/workspaces/widgets/package.json @@ -0,0 +1,7 @@ +{ + "name": "widgets", + "private": true, + "exports": { + "./TerminalView": "./TerminalView.tsx" + } +}