The Window component has been extracted from src/OS/Window/buildWindow.tsx into the v3.0 architecture at src/core/windowManager/Window/.
| File | Purpose |
|---|---|
src/core/windowManager/Window/Window.tsx |
Main Window component (full implementation) |
src/core/windowManager/Window/WindowHeader.tsx |
Window title bar with controls |
src/core/windowManager/Window/WindowContent.tsx |
Window content renderer (iframe/embed/component) |
src/core/windowManager/Window/window.types.ts |
Expanded TypeScript interfaces |
src/core/windowManager/Window/window.constants.ts |
Window constants and CSS class names |
src/core/windowManager/Window/index.ts |
Barrel exports |
| File | Change |
|---|---|
src/OS/Window/buildWindow.tsx |
Replaced with compatibility bridge re-export |
src/core/windowManager/index.ts |
Updated to export from Window/ |
src/core/windows/index.ts |
Fixed broken import paths |
src/core/desktop/desktop.types.ts |
Added missing React import |
src/core/state/state.types.ts |
Added missing React import |
src/core/windowManager/window.types.ts |
Added missing React import |
tsconfig.json |
Created (required for CRA TypeScript support) |
package.json |
Added typescript dependency |
src/OS/Window/buildWindow.tsx now re-exports from the new location:
export { default } from '../../core/windowManager/Window/Window';All existing imports (import Window from "../Window/buildWindow.tsx") continue to work.
New optional fields added to WindowData (backwards-compatible):
appId?: string- Application identifiericon?: string- Window iconminSize?: WindowSize- Minimum window dimensionsisFocused?: boolean- Focus stateisMinimized?: boolean- Minimized stateisOpen?: boolean- Open state
| File | Status |
|---|---|
src/OS/Window/buildWindow.tsx |
Compatibility bridge (re-export only) |
src/OS/Tools/taskbar.js |
Still manages window state (windows array, open/close) |
Taskbar Decomposition - Extract window state management from taskbar.js into a proper WindowManager:
- Move
windowsstate andhandleAppClick/removeWindowlogic - Create
src/core/windowManager/WindowManager.tsxas state container - Keep taskbar.js as a UI component that delegates to WindowManager
Before (v2.2):
src/OS/Tools/taskbar.jsownedwindowsstate viauseState([])handleAppClick(appName)created window data and added to stateremoveWindow(id)filtered window from state- App imports were at top of taskbar.js (tight coupling)
After (v3.0):
src/core/windowManager/WindowManager.tsxownswindowsstateopenWindow(appName)creates window data via app registry and adds to statecloseWindow(id)filters window from statefocusWindow(id)andupdateWindow(id, updates)prepared for future use- Taskbar receives state and actions as props (UI-only)
| File | Purpose |
|---|---|
src/core/windowManager/WindowManager.tsx |
Central window state owner, renders windows, provides actions |
src/core/windowManager/windowManager.types.ts |
TypeScript interfaces for WindowManager |
src/core/windowManager/windowManager.utils.ts |
App registry and window data creation |
| File | Change |
|---|---|
src/app.js |
Wraps Taskbar with WindowManager, passes state/actions as props |
src/OS/Tools/taskbar.js |
Receives props, removed window state ownership, uses openWindow instead of handleAppClick |
src/core/windowManager/index.ts |
Exports WindowManager and utilities |
| Logic | New Owner |
|---|---|
const [windows, setWindows] = useState([]) |
WindowManager.tsx |
handleAppClick(appName) function |
WindowManager.tsx → openWindow(appName) |
removeWindow(id) function |
WindowManager.tsx → closeWindow(id) |
| App component imports (Personalization, LinuxMode, etc.) | windowManager.utils.ts (app registry) |
uuidv4() import |
windowManager.utils.ts (uses crypto.randomUUID()) |
os:app_run event listener |
WindowManager.tsx |
interface WindowManagerActions {
openWindow: (appName: string) => void;
closeWindow: (id: string) => void;
focusWindow: (id: string) => void; // Prepared for future
updateWindow: (id: string, updates: Partial<WindowData>) => void; // Prepared for future
}windowManager.utils.ts contains a centralized app registry:
const APP_REGISTRY: Record<string, AppConfig> = {
settings: { title: 'Settings', size: {...}, src: '...' },
personalization: { title: 'Personalization', size: {...}, component: Personalization },
// ... more apps
};This replaces the switch statement that was previously in taskbar.js.
App
└── WindowManager (owns windows state)
├── <div id="window-frame"> (renders Window components)
└── Taskbar (receives props: windows, openWindow, closeWindow, ...)
WindowManager uses a render props pattern to pass state and actions to Taskbar.
src/OS/Window/buildWindow.tsxcontinues to re-export from v3.0- Taskbar props are optional (backwards-compatible if someone uses Taskbar without WindowManager)
- All existing event listeners (
os:reload,os:reload_complete) preserved
| File | Status |
|---|---|
src/OS/Window/buildWindow.tsx |
Compatibility bridge (re-export only) |
src/OS/Tools/taskbar/appSwitcher.tsx |
Reads windows from DOM (MutationObserver), not state |
src/core/windowManager/Window/Window.tsx |
Handles focus via DOM classes, not centralized state |
focusWindow()does not yet affect z-index (prepared for future)updateWindow()is available but not yet used by any component- AppSwitcher reads windows from DOM, not from WindowManager state
- Window position/size not yet tracked in central state (managed by interactjs)
Application Registry + App Manifest Foundation:
- Create central app registry in
src/core/apps/ - Define AppManifest interface for application metadata
- Move app component imports out of WindowManager utils
- Prepare for lazy loading and single-instance apps
Before (v2.2 → Phase 2):
src/core/windowManager/windowManager.utils.tscontained app imports and registry- WindowManager directly imported all application components
- App metadata was mixed with window creation logic
- No separation between "what apps exist" and "how windows work"
After (v3.0):
src/core/apps/contains the central Application RegistryAppManifestinterface defines application metadata- WindowManager uses registry via
getApp(appId)instead of direct imports - Clear separation: App Registry knows what apps exist, WindowManager knows which windows are running
interface AppManifest {
id: string; // Stable identifier (e.g., 'linux-mode')
name: string; // Display name (e.g., 'Linux Mode Terminal')
description?: string; // Short description
icon?: string; // Icon identifier (future)
component?: React.ComponentType<any>; // React component
category?: 'system' | 'internet' | 'media' | 'tools' | 'utilities';
defaultSize?: { width: number; height: number };
minSize?: { width: number; height: number };
singleInstance?: boolean; // Prevent multiple windows (future)
isSystemApp?: boolean; // System vs user app
type?: 'iframe' | 'embed' | 'internal-component';
src?: string; // URL for iframe/embed apps
version?: string; // App version (future)
}| File | Purpose |
|---|---|
src/core/apps/app.types.ts |
AppManifest interface and related types |
src/core/apps/registry.ts |
Central app registry with all applications registered |
src/core/apps/index.ts |
Barrel exports for app registry |
| File | Change |
|---|---|
src/core/windowManager/windowManager.utils.ts |
Now imports from app registry instead of directly importing components |
src/core/windowManager/index.ts |
Added app registry exports |
// Get a single app
getApp(appId: string): AppManifest | undefined
// Get all apps
getAllApps(): AppManifest[]
// Get apps by category
getAppsByCategory(category: string): AppManifest[]
// Check if app exists
isAppRegistered(appId: string): boolean
// Get all app IDs
getRegisteredAppIds(): string[]
// Get system/user apps
getSystemApps(): AppManifest[]
getUserApps(): AppManifest[]
// Search apps
searchApps(query: string): AppManifest[]| App ID | Name | Category | Component Location |
|---|---|---|---|
settings |
Settings | system | iframe (internal route) |
personalization |
Personalization | system | src/pages/Personalization/ |
google |
internet | iframe (external) | |
facebook |
internet | iframe (external) | |
bing |
Bing | internet | iframe (external) |
calculator |
Calculator | utilities | iframe (external) |
mplayer |
MPlayer | media | src/pages/MPlayer/ |
linuxmode |
Linux Mode Terminal | tools | src/pages/LinuxMode/ |
devzone |
DevZone | tools | src/pages/DevZone/ |
winsync |
WinSync | tools | src/pages/WinSync/ |
kdialer |
KDialer | utilities | src/pages/KDialer/ |
toolsapp |
Tools | tools | src/pages/ToolsApp/ |
Applications remain in src/pages/ during this phase:
| Directory | App ID |
|---|---|
src/pages/Personalization/ |
personalization |
src/pages/LinuxMode/ |
linuxmode |
src/pages/DevZone/ |
devzone |
src/pages/WinSync/ |
winsync |
src/pages/KDialer/ |
kdialer |
src/pages/MPlayer/ |
mplayer |
src/pages/ToolsApp/ |
toolsapp |
src/pages/Settings/ |
settings (iframe) |
All existing app IDs remain unchanged:
- Taskbar buttons use same IDs (
"google","facebook","bing") - Start Menu handlers use same IDs (
"settings","personalization", etc.) os:app_runevents use same IDs- No breaking changes to existing callers
App Registry (src/core/apps/)
├── Knows: what apps exist, their metadata
└── Does NOT know: which windows are open
WindowManager (src/core/windowManager/)
├── Knows: which windows are open, window lifecycle
└── Uses: getApp(appId) to create windows from registry
Taskbar / Start Menu
├── Knows: how to present apps, user interactions
└── Uses: openWindow(appId) to request window creation
Not implemented in this phase.
All app components are eagerly imported in src/core/apps/registry.ts.
The AppManifest interface is prepared for future lazy loading:
// Future concept (not yet used)
loader?: () => Promise<{ default: React.ComponentType<any> }>Lazy loading will be considered in a future phase after verifying build optimization needs.
Prepared but not enforced.
AppManifest includes singleInstance?: boolean field.
Currently only settings is marked as singleInstance: true.
The WindowManager does not yet enforce single-instance behavior - duplicate windows can still be opened. This will be implemented in a future phase.
- App components still imported eagerly (no code splitting)
- Single-instance not enforced
- App icons not yet implemented
- App versions not tracked
- No dynamic app registration (apps hardcoded in registry)
System Surfaces Extraction:
- Extract system UI components from legacy OS folders into v3.0 core architecture
- Create layout types foundation for future adaptive positioning
- Prepare components so they do not create unnecessary architectural limitations
- Maintain backwards compatibility through compatibility bridges
| Component | Legacy Path | New Path | Status |
|---|---|---|---|
| Clock | src/OS/Tools/time.js |
src/core/system/surfaces/Clock/Clock.tsx |
Extracted |
| AppSwitcher | src/OS/Tools/taskbar/appSwitcher.tsx |
src/core/system/surfaces/AppSwitcher/AppSwitcher.tsx |
Extracted |
| StartMenu | src/OS/Tools/menuStart.js |
src/core/system/surfaces/StartMenu/StartMenu.tsx |
Extracted |
| Taskbar | src/OS/Tools/taskbar.js |
src/core/system/surfaces/Taskbar/Taskbar.tsx |
Extracted |
| File | Purpose |
|---|---|
src/core/system/layout/layout.types.ts |
ScreenEdge, LayoutMode, SystemLayoutPreferences types |
src/core/system/layout/index.ts |
Layout type exports |
src/core/system/surfaces/Clock/Clock.tsx |
Clock component (functional, with hooks) |
src/core/system/surfaces/Clock/index.ts |
Clock barrel exports |
src/core/system/surfaces/AppSwitcher/AppSwitcher.tsx |
AppSwitcher component (preserves DOM-based behavior) |
src/core/system/surfaces/AppSwitcher/index.ts |
AppSwitcher barrel exports |
src/core/system/surfaces/StartMenu/StartMenu.tsx |
StartMenu component (preserves existing behavior) |
src/core/system/surfaces/StartMenu/index.ts |
StartMenu barrel exports |
src/core/system/surfaces/Taskbar/Taskbar.tsx |
Taskbar component (with position prop support) |
src/core/system/surfaces/Taskbar/index.ts |
Taskbar barrel exports |
src/core/system/surfaces/index.ts |
Surfaces barrel exports |
| File | Change |
|---|---|
src/core/system/index.ts |
Added layout and surfaces exports |
src/OS/Tools/taskbar.js |
Replaced with compatibility bridge |
src/OS/Tools/menuStart.js |
Replaced with compatibility bridge |
src/OS/Tools/time.js |
Replaced with compatibility bridge |
src/OS/Tools/taskbar/appSwitcher.tsx |
Replaced with compatibility bridge |
| Legacy Path | Bridge Implementation |
|---|---|
src/OS/Tools/taskbar.js |
export { Taskbar as default } from '../../core/system/surfaces/Taskbar'; |
src/OS/Tools/menuStart.js |
export { StartMenu as default } from '../../core/system/surfaces/StartMenu'; |
src/OS/Tools/time.js |
export { Clock as default } from '../../core/system/surfaces/Clock'; |
src/OS/Tools/taskbar/appSwitcher.tsx |
export { AppSwitcher as default } from '../../../core/system/surfaces/AppSwitcher'; |
All existing imports continue to work through these bridges.
// Screen edge positions for system surfaces
type ScreenEdge = 'top' | 'right' | 'bottom' | 'left';
// Layout mode for system surfaces
type LayoutMode = 'adaptive' | 'custom';
// System layout preferences for future configuration
interface SystemLayoutPreferences {
mode: LayoutMode;
taskbarPosition: ScreenEdge;
}
// Default layout preferences matching current v2.2 behavior
const DEFAULT_LAYOUT_PREFERENCES: SystemLayoutPreferences = {
mode: 'adaptive',
taskbarPosition: 'bottom',
};Taskbar:
- Now accepts optional
position?: ScreenEdgeprop - Defaults to
'bottom'(current behavior) - Uses
data-positionattribute for future CSS styling - No visual changes - remains at bottom
Clock:
- Converted from class component to functional component with hooks
- Accepts optional
position?: ScreenEdgeprop - Preserves all existing behavior
AppSwitcher:
- Preserves DOM-based window reading (MutationObserver)
- No changes to behavior
- Documented as technical debt for future WindowManager integration
StartMenu:
- Preserves all existing behavior
- App launching callbacks unchanged
- No visual changes
| File | Status |
|---|---|
src/OS/Tools/taskbar.js |
Compatibility bridge only |
src/OS/Tools/menuStart.js |
Compatibility bridge only |
src/OS/Tools/time.js |
Compatibility bridge only |
src/OS/Tools/taskbar/appSwitcher.tsx |
Compatibility bridge only |
src/app.js |
Still imports from legacy path (works through bridge) |
-
AppSwitcher reads windows from DOM using MutationObserver
- Should eventually use WindowManager's window list API
- Current behavior preserved for backwards compatibility
-
Theme switching uses direct DOM manipulation
taskbar.jsmanipulatesdocument.bodyclasses- Should eventually use CSS custom properties or context
-
Accent color injection creates
<style>elements in<head>- Should eventually use CSS variables or theme context
The architecture now supports:
- Taskbar position via
positionprop (currently locked to'bottom') - CSS
data-positionattribute for future edge-specific styling - Layout preferences type for future settings UI
- No hardcoded assumptions about screen edge in component logic
Future phases can implement:
- Settings UI for taskbar position
- CSS for different edge positions
- Adaptive layout engine
- User preferences persistence
Desktop Runtime Extraction + System Bar Foundation:
- Extract core Desktop Runtime from legacy OS structure
- Create layered desktop architecture
- Prepare foundation for future system bars and adaptive layout
- Maintain backwards compatibility
src/core/desktop/
├── DesktopRuntime.tsx # Main orchestrator for desktop environment
├── Desktop.tsx # Desktop container (existing)
├── DesktopLayer.tsx # Z-index layering (existing)
├── desktop.types.ts # Type definitions (updated)
├── desktop.constants.ts # Constants (new)
├── index.ts # Barrel exports (updated)
└── layers/
├── BackgroundLayer.tsx # Wallpaper and background effects
├── DesktopContentLayer.tsx # Desktop-level content
├── WindowLayer.tsx # Window rendering layer
├── SystemSurfaceLayer.tsx # System UI layer
├── OverlayLayer.tsx # Dialogs and overlays
└── index.ts
| File | Purpose |
|---|---|
src/core/desktop/DesktopRuntime.tsx |
Main desktop orchestrator, composes all layers |
src/core/desktop/desktop.constants.ts |
Layer z-index values, CSS class names |
src/core/desktop/layers/BackgroundLayer.tsx |
Wallpaper and background effects layer |
src/core/desktop/layers/DesktopContentLayer.tsx |
Desktop content layer (icons, widgets) |
src/core/desktop/layers/WindowLayer.tsx |
Window rendering layer |
src/core/desktop/layers/SystemSurfaceLayer.tsx |
System UI layer (Taskbar, bars) |
src/core/desktop/layers/OverlayLayer.tsx |
Dialogs, notifications, overlays |
src/core/desktop/layers/index.ts |
Layer barrel exports |
src/core/system/surfaces/SystemBar/SystemBar.tsx |
Reusable system bar with slot pattern |
src/core/system/surfaces/SystemBar/index.ts |
SystemBar barrel exports |
| File | Change |
|---|---|
src/core/desktop/desktop.types.ts |
Added DesktopRuntimeProps, WindowManagerContext |
src/core/desktop/index.ts |
Added DesktopRuntime and layer exports |
src/core/system/surfaces/index.ts |
Added SystemBar exports |
src/core/system/index.ts |
Added SystemBar exports |
src/core/index.ts |
Added DesktopRuntime and layer exports |
| Layer | Z-Index | Responsibility |
|---|---|---|
| BackgroundLayer | 0 | Wallpaper, background effects |
| DesktopContentLayer | 1 | Desktop icons, widgets (future) |
| WindowLayer | 10 | Window rendering (via WindowManager) |
| SystemSurfaceLayer | 100 | Taskbar, system bars, start menu |
| OverlayLayer | 1000 | Dialogs, notifications, search |
DesktopRuntime
├── WindowManager (single source of truth for windows)
│ ├── BackgroundLayer (wallpaper)
│ ├── #window-frame (window rendering)
│ ├── SystemSurfaceLayer
│ │ └── Taskbar (with position prop)
│ └── OverlayLayer (future)
└── Children (Bootloader, etc.)
// SystemBar with slot pattern
<SystemBar edge="top">
<SystemBar.Left>
{/* Weather, launcher */}
</SystemBar.Left>
<SystemBar.Center>
{/* Search */}
</SystemBar.Center>
<SystemBar.Right>
{/* Time, system info */}
</SystemBar.Right>
</SystemBar>
// Props
interface SystemBarProps {
edge?: ScreenEdge; // 'top' | 'right' | 'bottom' | 'left'
children?: React.ReactNode;
className?: string;
style?: React.CSSProperties;
}DesktopRuntime uses the existing WindowManager pattern:
- WindowManager remains single source of truth for window state
- DesktopRuntime composes WindowManager (does NOT own window state)
- Taskbar receives window state/actions as props
| Component | Status |
|---|---|
src/OS/background.js |
Preserved as-is, not yet migrated |
src/OS/bootloader.js |
Preserved as-is, not yet migrated |
src/app.js |
Still uses legacy structure |
Note: src/OS/background.js contains context menu and version display logic that could be migrated in a future phase. For now, it remains untouched to preserve backwards compatibility.
The architecture now supports:
- Layered desktop with clear z-index separation
- SystemBar component with position-agnostic design
- ScreenEdge type for future taskbar positioning
- No hardcoded assumptions about screen edges in architectural logic
Future phases can implement:
- Movable taskbar (top/right/bottom/left)
- Adaptive layout engine
- Custom layout settings
- Top system bar
- Bottom system area
| File | Status |
|---|---|
src/OS/background.js |
Legacy, not yet migrated |
src/OS/bootloader.js |
Legacy, not yet migrated |
src/app.js |
Legacy, uses legacy imports |
- DesktopRuntime does not yet use DesktopRuntime in app.js
- Background.js not yet migrated to BackgroundLayer
- SystemBar not yet integrated into DesktopRuntime
- OverlayLayer prepared but not used
Runtime Integration + Legacy Desktop Migration:
- Migrate
src/OS/background.jslogic to BackgroundLayer - Update
src/app.jsto use DesktopRuntime - Integrate SystemBar into DesktopRuntime
- Begin migrating bootloader to v3.0
- Complete legacy OS folder extraction
src/app.js
├── LoadOS (bootloader) - renders splash screen
├── After 3 seconds:
│ ├── WindowManager
│ │ ├── Taskbar
│ │ └── Background (from src/OS/background.js)
│ └── LoadOS (always rendered)
src/app.js
├── DesktopRuntime (isBooted state managed here)
│ ├── WindowManager
│ │ ├── BackgroundLayer (migrated from background.js)
│ │ ├── SystemSurfaceLayer
│ │ │ └── Taskbar
│ │ └── OverlayLayer (future)
├── LoadOS (bootloader) - still renders splash screen
| File | Purpose |
|---|---|
| None | No new files created in this phase |
| File | Change |
|---|---|
src/app.js |
Now uses DesktopRuntime instead of direct legacy imports |
src/core/desktop/DesktopRuntime.tsx |
Accepts isBooted prop, removed duplicate boot logic |
src/core/desktop/desktop.types.ts |
Added isBooted prop to DesktopRuntimeProps |
src/core/desktop/layers/BackgroundLayer.tsx |
Migrated all background.js behavior |
src/core/desktop/layers/SystemSurfaceLayer.tsx |
Simplified, positioned at bottom |
src/OS/background.js |
Replaced with compatibility bridge |
package.json |
Version updated to 3.0.0 |
| Original | New Location | Status |
|---|---|---|
src/OS/background.js |
src/core/desktop/layers/BackgroundLayer.tsx |
Fully migrated |
src/OS/background.css |
src/core/desktop/layers/BackgroundLayer.tsx |
CSS imported from original location |
| Component | Layer | Status |
|---|---|---|
| BackgroundLayer | Background (z-index: 0) | Active - migrated from background.js |
| WindowManager | Window (z-index: 10) | Active - renders windows |
| SystemSurfaceLayer | System (z-index: 100) | Active - contains Taskbar |
| Taskbar | System | Active - with position="bottom" |
| OverlayLayer | Overlay (z-index: 1000) | Prepared - not yet used |
COMPLETED
BackgroundLayer now includes all behavior from original background.js:
- Context menu (right-click)
- Version display ("OnerOS Web (Preview) 3.0.0")
- Reload UI event dispatch
- Start Menu event dispatch
- All existing interactions
Original src/OS/background.js is now a compatibility bridge:
export { default } from '../../core/desktop/layers/BackgroundLayer';COMPLETED
SystemSurfaceLayer is now actively used in DesktopRuntime:
- Positioned at bottom of screen (z-index: 100)
- Renders Taskbar with position="bottom"
- Preserves existing layout behavior
PREPARED - NOT YET VISIBLE
SystemBar component exists but is not yet rendered in DesktopRuntime. This preserves the current v2.2 visual appearance.
Future phases can integrate SystemBar for top/bottom system areas.
NOT MIGRATED - Intentionally preserved
src/OS/bootloader.js remains as-is:
- Simple component (17 lines)
- Sets body styles and shows splash screen
- No risk in keeping as legacy
- Can be migrated in future phase if desired
| Legacy Path | Bridge |
|---|---|
src/OS/background.js |
Re-exports BackgroundLayer |
| File | Status | Notes |
|---|---|---|
src/OS/bootloader.js |
Active | Simple, no migration needed yet |
src/OS/background.js |
Bridge only | Re-exports from BackgroundLayer |
src/OS/background.css |
Active | Imported by BackgroundLayer |
src/OS/Tools/taskbar.js |
Bridge only | Re-exports from v3.0 Taskbar |
src/OS/Tools/menuStart.js |
Bridge only | Re-exports from v3.0 StartMenu |
src/OS/Tools/time.js |
Bridge only | Re-exports from v3.0 Clock |
src/OS/Tools/taskbar/appSwitcher.tsx |
Bridge only | Re-exports from v3.0 AppSwitcher |
src/OS/Window/buildWindow.tsx |
Bridge only | Re-exports from v3.0 Window |
Package version updated from 2.2.0 to 3.0.0 to reflect the architectural milestone.
Build: SUCCESS
Bundle size: 656.64 kB (gzipped)
Warnings: Pre-existing (aria-disabled, unused vars)
None. All existing functionality preserved:
- Boot sequence works correctly
- Background renders with context menu
- Taskbar renders at bottom
- Windows open and close correctly
- Start Menu works
- Clock works
- AppSwitcher works
- All os:* events still work
Polish + Remaining Legacy Cleanup:
- Migrate bootloader to v3.0 (optional)
- Remove remaining compatibility bridges
- Clean up unused legacy code
- Optimize bundle size
- Add TypeScript strict mode
src/
├── app.js # Root App component (boot sequence + layout)
├── app.css # All global styles (1445 lines)
├── index.js # Entry point with React Router
├── logo.svg
├── reportWebVitals.js
├── setupTests.js
├── OS/
│ ├── background.js # Desktop wallpaper + context menu
│ ├── background.css # Background-specific styles
│ ├── bootloader.js # Boot splash screen
│ ├── Tools/
│ │ ├── menuStart.js # Start menu component
│ │ ├── taskbar.js # Taskbar + window management (central orchestrator)
│ │ ├── time.js # Clock component
│ │ └── taskbar/
│ │ └── appSwitcher.tsx # Alt-Tab style app switcher
│ └── Window/
│ └── buildWindow.tsx # Draggable/resizable window component
├── pages/
│ ├── DevZone/devzone.jsx # Developer tools (JSON, Base64, Regex, etc.)
│ ├── KDialer/kdialer.jsx # Phone dialer app
│ ├── LinuxMode/linuxmode.jsx # Simulated Linux terminal
│ ├── MPlayer/mplayer.jsx # Music player app
│ ├── Personalization/personalization.jsx # Wallpaper + accent color settings
│ ├── Settings/homescreen.jsx # Placeholder settings page
│ ├── ToolsApp/toolsapp.jsx # Screenshot, monitor, clipboard, recorder, color picker, notes
│ └── WinSync/winsync.jsx # Clipboard sync, file transfer, QR, link shortener, notes
└── lambda/
├── async-dadjoke.js # Netlify serverless function
└── hello.js # Netlify serverless function
Architecture: Create React App + React 18 + React Router v6 State Management: Local state + localStorage + Custom DOM Events Styling: Plain CSS (single global file + per-component CSS) Window System: interactjs for drag/resize, custom Window component
src/
├── app/
│ ├── App.tsx # Root App component (future)
│ ├── providers/ # Context providers (future)
│ └── routes/ # Route definitions (future)
│
├── core/
│ ├── desktop/
│ │ ├── Desktop.tsx # Desktop container
│ │ ├── DesktopLayer.tsx # Z-index layering
│ │ ├── desktop.types.ts # Desktop type definitions
│ │ └── index.ts
│ ├── windowManager/
│ │ ├── Window/
│ │ │ ├── Window.tsx # Main window component
│ │ │ ├── WindowHeader.tsx # Title bar with controls
│ │ │ ├── WindowContent.tsx # Content renderer
│ │ │ ├── window.types.ts # Window data types
│ │ │ ├── window.constants.ts # Window constants
│ │ │ └── index.ts
│ │ ├── windowManager.types.ts # Manager types (future)
│ │ ├── windowManager.constants.ts # Manager constants
│ │ └── index.ts
│ ├── system/
│ │ ├── topbar/
│ │ │ ├── TopBar.tsx # Future top bar
│ │ │ ├── topbar.types.ts
│ │ │ └── index.ts
│ │ ├── bottombar/
│ │ │ ├── BottomBar.tsx # Future bottom bar
│ │ │ ├── bottombar.types.ts
│ │ │ └── index.ts
│ │ ├── bootloader/
│ │ │ ├── Bootloader.tsx
│ │ │ └── index.ts
│ │ └── index.ts
│ ├── state/
│ │ ├── state.types.ts # Global state types
│ │ └── index.ts
│ └── index.ts
│
├── features/
│ ├── search/
│ │ ├── Search.tsx
│ │ ├── search.types.ts
│ │ └── index.ts
│ ├── widgets/
│ │ ├── Widgets.tsx
│ │ ├── widgets.types.ts
│ │ └── index.ts
│ ├── notifications/
│ │ ├── Notifications.tsx
│ │ ├── notifications.types.ts
│ │ └── index.ts
│ ├── settings/
│ │ ├── settings.types.ts
│ │ └── index.ts
│ ├── appearance/
│ │ ├── Appearance.tsx
│ │ ├── appearance.types.ts
│ │ └── index.ts
│ └── index.ts
│
├── apps/
│ ├── file-explorer/index.ts
│ ├── browser/index.ts
│ ├── settings/index.ts
│ ├── shared/index.ts
│ └── index.ts
│
├── components/
│ ├── ui/index.ts
│ ├── layout/index.ts
│ ├── shared/index.ts
│ └── index.ts
│
├── hooks/index.ts
├── services/index.ts
├── utils/index.ts
├── types/index.ts
├── constants/index.ts
│
├── styles/
│ ├── tokens/
│ │ ├── colors.css # Design tokens: colors
│ │ ├── spacing.css # Design tokens: spacing
│ │ ├── radius.css # Design tokens: border radius
│ │ └── index.css
│ ├── globals/
│ │ ├── reset.css # CSS reset
│ │ ├── base.css # Base typography
│ │ └── index.css
│ └── legacy/
│ └── app.css # Original v2.2 global styles (moved)
│
├── assets/
│ └── images/
│
├── legacy/
│ └── README.md # Migration documentation
│
├── OS/ # [LEGACY] Original OS components
├── pages/ # [LEGACY] Original application components
├── app.js # [LEGACY] Original root App component
├── app.css # [RE-EXPORT] Imports from styles/
└── index.js # [LEGACY] Entry point (unchanged)
| Original Location | New Location | Status |
|---|---|---|
src/app.css (content) |
src/styles/legacy/app.css |
Moved; src/app.css now re-imports |
src/styles/tokens/colors.css |
New file | Created (extracted from app.css) |
src/styles/tokens/spacing.css |
New file | Created |
src/styles/tokens/radius.css |
New file | Created |
src/styles/globals/reset.css |
New file | Created (extracted from app.css) |
src/styles/globals/base.css |
New file | Created (extracted from app.css) |
| File/Directory | Reason |
|---|---|
src/OS/ |
Core OS components tightly coupled to taskbar.js |
src/pages/ |
All application components imported directly by taskbar.js |
src/app.js |
Root component, imports OS components |
src/index.js |
Entry point with router |
src/lambda/ |
Netlify serverless functions (unrelated to UI) |
- Move
src/OS/Window/buildWindow.tsx→src/core/windowManager/Window/ - Create re-export at old path for backwards compatibility
- Extract window state management from taskbar.js into a proper WindowManager
- Split
src/OS/Tools/taskbar.jsinto:src/core/system/bottombar/- Taskbar containersrc/core/system/bottombar/StartMenu.tsx- Start menusrc/core/system/bottombar/Clock.tsx- Clocksrc/core/system/bottombar/AppSwitcher.tsx- App switchersrc/core/system/bottombar/SearchBar.tsx- Search bar
- Create an app registry system in
src/apps/ - Move app definitions from taskbar.js switch statement to registry
- Support dynamic app loading
- Extract localStorage operations into
src/services/ - Create proper state management in
src/core/state/ - Move DOM event system to
src/services/
- Add
tsconfig.json - Convert
.jsfiles to.ts/.tsxincrementally - Start with leaf components (time.js, bootloader.js)
- Single monolithic CSS file -
app.cssis 1445 lines with all themes, all components, all responsive rules - No state management - All state is local + localStorage + DOM events
- Tight coupling - taskbar.js imports ALL app components directly
- Mixed file extensions -
.js,.jsx,.tsxused inconsistently - No TypeScript config - No
tsconfig.jsondespite having.tsxfiles - No path aliases - All imports use relative paths (
../../pages/...) - No lazy loading - All apps imported eagerly in taskbar.js
- DOM manipulation - Theme switching uses direct DOM manipulation
- No CSS modules - All styles are global
- No build optimization - CRA defaults, no code splitting
- taskbar.js - Central orchestrator; any changes here affect the entire OS
- buildWindow.tsx - Uses interactjs; drag/resize logic is complex
- Theme system - CSS class toggling on document.body; deeply coupled to app.css
- localStorage keys - Multiple components share localStorage; key changes break persistence
- DOM events - Custom events (os:reload, os:app_run) are used cross-component
- App imports - All apps are statically imported; switching to lazy loading requires careful handling
- Settings iframe - Settings opens in iframe via URL route; breaks if routing changes
- Never break existing imports - Always create re-exports at old paths
- Move one component at a time - Don't try to move everything at once
- Test after each move - Run
npm startto verify the app works - Keep legacy code working - Old code should continue functioning
- Create index.ts files - Use barrel exports for clean module boundaries
- Define types first - Create type definitions before moving components
- Extract services - Move localStorage operations to services before moving components
- Add path aliases - Configure webpack/vite aliases to simplify imports
Goal: Create the visual foundation for the OnerOS 2026 theme and Fluent Valley design system.
| File | Status | Contents |
|---|---|---|
src/styles/tokens/colors.css |
Extended | Accent, background, text, border, window, taskbar, menu, status, per-theme variables |
src/styles/tokens/spacing.css |
Unchanged | Spacing scale, layout dimensions, border widths |
src/styles/tokens/radius.css |
Unchanged | Border radius scale, per-theme radii |
src/styles/tokens/typography.css |
Extended | Font families, sizes, weights, line heights + Fluent Valley aliases |
src/styles/tokens/shadows.css |
Extended | Shadow scale + Fluent Valley elevation system |
src/styles/tokens/motion.css |
New | Duration scale, easing curves, reduced-motion support |
src/styles/tokens/surfaces.css |
New | Surface hierarchy, glass/translucency system with fallback |
src/styles/tokens/index.css |
Updated | Imports motion.css and surfaces.css |
Color Tokens (--fv-* prefix):
--fv-background,--fv-surface,--fv-surface-elevated,--fv-surface-floating--fv-text-primary,--fv-text-secondary,--fv-text-muted--fv-border-subtle,--fv-border-default,--fv-border-active--fv-accent,--fv-accent-hover,--fv-accent-subtle--fv-success,--fv-warning,--fv-error,--fv-info
Typography Tokens (--fv-font-*, --fv-line-height-*):
--fv-font-family,--fv-font-family-mono--fv-font-size-xsthrough--fv-font-size-3xl--fv-font-weight-regular,--fv-font-weight-medium,--fv-font-weight-semibold--fv-line-height-tight,--fv-line-height-normal,--fv-line-height-relaxed
Elevation Tokens (--fv-elevation-*):
--fv-elevation-0through--fv-elevation-4--fv-elevation-active
Motion Tokens (--fv-duration-*, --fv-ease-*, --fv-transition-*):
--fv-duration-instantthrough--fv-duration-slower--fv-ease-standard,--fv-ease-decelerate,--fv-ease-accelerate,--fv-ease-emphasized,--fv-ease-spring--fv-transition-fast,--fv-transition-normal,--fv-transition-slow
Surface Tokens (--fv-surface-*, --fv-glass-*):
--fv-surface-basethrough--fv-surface-overlay--fv-surface-card,--fv-surface-panel,--fv-surface-dialog--fv-surface-glass--fv-glass-opacity,--fv-glass-blur,--fv-glass-border,--fv-glass-bg
None. All existing tokens remain unchanged. New tokens are additive.
- Body class:
oneros2026-mode - Taskbar class:
oneros2026-theme - Theme ID: 6 (in THEMES array)
- CSS file:
src/styles/themes/oneros2026.css - Pattern: Same body class toggling as existing themes
- Integration: Added to
THEME_MODES,THEME_CLASSES,BODY_MODE_CLASSESconstants - Type:
DesktopThemeunion extended with'oneros2026' - Personalization: Selectable in Personalization app with
faMagicWandSparklesicon - Taskbar: Boot restoration and theme cycling support OnerOS 2026
Wallpaper
↓
Desktop
↓
Base Surface (--fv-surface-base)
↓
Elevated Surface (--fv-surface-elevated)
↓
Floating Surface (--fv-surface-floating)
↓
Interactive Element
Additional semantic surfaces: --fv-surface-card, --fv-surface-panel, --fv-surface-dialog, --fv-surface-overlay, --fv-surface-glass.
- Glass surfaces use
backdrop-filter: blur()with fallback @supports (backdrop-filter: blur(1px))enables glass effects@supports not (backdrop-filter: blur(1px))falls back to solid opaque backgrounds- Default blur: 12px (not extreme)
- Glass opacity: 0.75 (readable on complex wallpapers)
5-level elevation system (0-4) designed for soft depth:
- Level 0: No shadow
- Level 1: Subtle lift (cards, panels)
- Level 2: Elevated (dropdowns, popovers)
- Level 3: Floating (modals, dialogs)
- Level 4: Highest (tooltips, notifications)
- Active: Pressed state
Semantic font size scale (--fv-font-size-*) mapping to existing --text-* tokens.
System font stack preferred for performance. No external font dependencies added.
- Duration scale: instant (0ms), fast (100ms), normal (200ms), slow (350ms), slower (500ms)
- Easing: standard, decelerate, accelerate, emphasized, spring
- No GSAP or heavy animation libraries
@media (prefers-reduced-motion: reduce) block in motion.css reduces all duration tokens to 0ms. This is a global mechanism — any future animation using --fv-duration-* or --fv-transition-* will automatically be disabled.
UI primitives (AppShell, Button, EmptyState, Panel, Section) already consume CSS custom properties. They automatically inherit Fluent Valley tokens when OnerOS 2026 theme is active. No component changes required in this phase.
| Metric | Before (v3.0) | After (v3.1 Phase 1) | Delta |
|---|---|---|---|
| Main JS (gzip) | 656.64 kB | 637.25 kB | -19.39 kB |
| Main CSS (gzip) | ~10.35 kB | 11.94 kB | +1.59 kB |
None. All work uses existing CSS architecture and variables.
- Bootloader: Working
- Desktop: Unchanged
- WindowManager: Unchanged
- Window open/close: Unchanged
- Taskbar: Updated (backward compatible)
- StartMenu: Working
- AppSwitcher: Working
- Settings: Working
- Personalization: Updated (new theme option)
- Themes: All existing themes functional
- Accent colors: Working
- Wallpapers: Working
- Lazy-loaded apps: Working
- Desktop: Working
- Mobile: Working
No regressions found.
- Begin applying Fluent Valley surface tokens to existing components
- Migrate Taskbar to consume
--fv-surface-*and--fv-glass-*tokens - Apply elevation tokens to window components
- Implement Fluent Valley motion tokens for window open/close transitions
- Consider CSS-only micro-interactions (hover states, focus rings)
- Migrate app shell components to use semantic surface tokens
Goal: Complete and stabilize the theme and appearance architecture. One coherent appearance flow.
- THEMES array duplicated in 3 locations:
personalization.jsx,Taskbar.tsx(boot),Taskbar.tsx(toggle) THEME_MODES,THEME_CLASSES,BODY_MODE_CLASSESconstants exported but never imported- Theme application: manual class removal + switch/case in each location
- Accent colors:
document.createElement('style')injection in 3 locations - No centralized theme data, no centralized accent logic
- Adding a new theme required updating 3+ files with hardcoded class lists
Theme Registry (single source of truth)
↓
Appearance Service (single entry point)
↓
DOM manipulation + localStorage persistence
↓
CSS variables → UI rendering
- Theme Registry (
src/core/system/appearance/themeRegistry.ts): Single THEMES array, class lists, helper functions - Appearance Service (
src/core/system/appearance/appearance.ts):setTheme(),restoreAppearance(),resetAppearance() - Accent Module (
src/core/system/appearance/accent.ts):applyAccentColor()via CSS custom properties, zero style injection - Personalization imports from appearance module, no duplicate data
- Taskbar imports from appearance module, no duplicate data
- Linux Mode imports
applyAccentColor(), no style injection
src/core/system/appearance/ is the single owner of:
- Theme selection and application
- Accent color management
- Wallpaper management
- Persistence (localStorage)
- Boot restoration
No duplicate state owners exist.
User selects theme
↓
setTheme(themeId)
↓
applyThemeToDOM(themeId) → body/taskbar class toggling
↓
localStorage.setItem('os_theme', id)
↓
On boot: restoreAppearance()
↓
getStoredThemeId() → read + validate
↓
applyThemeToDOM(themeId)
↓
restoreAccentColor() → applyAccentColor() via CSS vars
↓
restoreWallpaper()
Before: 3 separate document.createElement('style') injections generating CSS strings.
After: Single applyAccentColor(color) function that sets CSS custom properties on document.documentElement:
--color-accent,--color-accent-dark,--color-accent-light--color-accent-hover,--color-accent-active,--color-accent-subtle,--color-accent-contrast--fv-accent,--fv-accent-hover,--fv-accent-active,--fv-accent-subtle,--fv-accent-contrast
No <style> elements created. All rendering via CSS variables.
| Location | Before | After |
|---|---|---|
personalization.jsx |
document.createElement('style') with 6 CSS rules |
applyAccentColor() → CSS vars |
Taskbar.tsx |
document.createElement('style') with 6 CSS rules |
restoreAppearance() → CSS vars |
linuxmode.jsx |
document.createElement('style') with 14 CSS rules |
applyAccentColor() → CSS vars |
All 3 injection sites eliminated. Legacy injected styles are cleaned up by removeInjectedAccentStyle().
New accent variant tokens (all themes + :root):
--color-accent-hover--color-accent-active--color-accent-subtle--color-accent-contrast--fv-accent-hover--fv-accent-active--fv-accent-subtle--fv-accent-contrast
New storage key:
STORAGE_KEYS.THEME = 'os_theme'
DEFAULT_THEME_ID = 0(Modern) — current defaultFALLBACK_THEME_ID = 0— safe fallback for invalid values- To change default for new users: change
DEFAULT_THEME_IDto6 - Returning users:
getStoredThemeId()reads localStorage, preserves choice - Invalid values:
validateThemeId()returnsFALLBACK_THEME_ID - New users with no stored value:
DEFAULT_THEME_IDis used
- All stored
os_themevalues (0-6) continue to work - All stored
os_accent_colorvalues continue to work - All stored
os_wallpaper_*values continue to work - No breaking changes to localStorage schema
- Boot restoration validates and falls back safely
All 7 themes continue to work exactly as before:
- Modern (0), Centered (1), Win95 (2), WinXP (3), macOS (4), Ubuntu (5), OnerOS 2026 (6)
- Theme-specific CSS variable overrides unchanged
- Per-theme component styling unchanged
- Legacy
app.csstheme rules unchanged
Wallpaper is independent from theme and accent:
applyWallpaper(type, color)— DOM manipulation onlypersistWallpaper(type, color)— localStorage onlyrestoreWallpaper()— reads + applies from localStorage- Changing wallpaper does not affect theme or accent
- Changing theme does not affect wallpaper
| Metric | Phase 1 | Phase 2 | Delta |
|---|---|---|---|
| Main JS (gzip) | 637.25 kB | 626.0 kB | -11.25 kB |
| Main CSS (gzip) | 11.94 kB | 12.24 kB | +0.30 kB |
JS decreased because duplicated theme arrays were removed from Personalization and Taskbar. CSS increased slightly due to new accent variant tokens in each theme block.
- Legacy
app.css(1463 lines) remains unrefactored --color-accent-darkstill used by app CSS (toolsapp, winsync, devzone, mplayer, kdialer) — kept for backward compatibilityTHEME_MODES,THEME_CLASSES,BODY_MODE_CLASSESconstants still exported but now redundant with themeRegistry — can be deprecated in Phase 3resetToDefault()in Personalization still manually resets.menu-squarestyles — legacy compatibility
- Begin applying Fluent Valley surface tokens to existing components
- Migrate Taskbar to consume
--fv-surface-*and--fv-glass-*tokens - Apply elevation tokens to window components
- Implement Fluent Valley motion tokens for window open/close transitions
- Consider CSS-only micro-interactions (hover states, focus rings)
- Deprecate
THEME_MODES/THEME_CLASSES/BODY_MODE_CLASSESin favor of themeRegistry exports
Goal: First major visible Fluent Valley system UI — TopBar, BottomBar, surface styling, responsive behavior.
New component at src/core/system/topbar/TopBar.tsx:
- Left: Weather surface (lightweight placeholder, no API dependency)
- Center: Search surface with Fluent Valley glass styling
- Right: Clock (reuses date logic, no duplication)
Uses Fluent Valley tokens: --fv-surface-glass, --fv-glass-blur, --fv-glass-border, --fv-transition-*.
Renders as #os-topbar with position: fixed; top: 0; z-index: 200.
New component at src/core/system/bottombar/BottomBar.tsx — 3-zone layout:
- Left: Widgets / system launcher area
- Center: Applications (absolutely centered relative to viewport)
- Right: System controls / notifications
Center zone uses position: absolute; left: 50%; transform: translateX(-50%) to remain optically centered regardless of left/right content width.
The existing Taskbar component was restructured with the 3-zone layout:
- Left zone: Menu button (
.menu+.fv-taskbar-menu) - Center zone: Application icons (
.apps+.fv-taskbar-center) - Right zone: Clock (
.fv-taskbar-clock)
All legacy class names preserved (.menu, .menu-square, .apps, #os-taskbar, #clock) for backward compatibility with theme CSS.
DesktopRuntime.tsx now renders:
<BackgroundLayer />
<SystemSurfaceLayer> ← now full-viewport, pointer-events: none
<TopBar /> ← position: fixed, top
<Taskbar /> ← position: fixed, bottom
</SystemSurfaceLayer>
Changed from bottom: 0; height: auto to top: 0; width: 100%; height: 100%; pointer-events: none — supports future left/right positioning.
AppSwitcher CSS updated with Fluent Valley tokens:
--fv-surface-elevatedfor background--fv-border-subtlefor borders--fv-elevation-4for shadowfv-fade-inandfv-scale-inanimations- Reduced motion support
All existing functionality preserved: keyboard navigation, context menu, focus management.
StartMenu remains fully functional inside the Taskbar. Legacy CSS classes (.menu-layout, .app-tile, .menu-elm, etc.) unchanged.
Added Fluent Valley elevation tokens to base .window class:
- Default:
--fv-elevation-2(resting),--fv-elevation-3(active) - OnerOS 2026: Same tokens with theme-specific shadow values
- Transition:
--fv-transition-normalfor smooth elevation changes
No changes to drag, resize, maximize, or WindowManager behavior.
System surfaces use:
--fv-surface-glass/--fv-glass-blur/--fv-glass-border--fv-elevation-1through--fv-elevation-4--fv-border-subtle--fv-transition-fast/--fv-transition-normal--fv-duration-*/--fv-ease-*
All system bars use @supports (backdrop-filter: blur(1px)) pattern:
- Supported: translucent glass with blur
- Not supported: solid
--bg-primaryfallback
fv-fade-in— AppSwitcher overlayfv-scale-in— AppSwitcher panel--fv-transition-fast— button hover/press--fv-transition-normal— surface background transitionsprefers-reduced-motion: reduce— all transitions/animations disabled
| Breakpoint | TopBar | BottomBar |
|---|---|---|
| > 768px | Full (weather + search + clock) | Full (menu + apps + clock) |
| ≤ 768px | Compact (no weather label, smaller search) | Compact (smaller icons) |
| ≤ 480px | Minimal (icon only weather, tiny search) | Minimal (smaller buttons) |
| ≤ 360px | Ultra-compact | Ultra-compact |
| Touch | Larger touch targets (44px min) | Larger touch targets (44px min) |
- All system bars have
roleandaria-label - Menu button:
role="button",aria-expanded,aria-label - App buttons:
aria-labelon each - Search:
aria-label="Search" - Clock:
aria-labelwith current time - Focus-visible outlines on all interactive elements
- No hover-only functionality
SystemSurfaceLayerspans full viewport (not just bottom)ScreenEdgetype already defined in layout.types.tsSystemLayoutPreferencesinterface exists- Bars use
position: fixed— can be repositioned via CSS - No deep coupling of Taskbar = bottom in the runtime
Removed from src/constants/index.ts:
THEME_MODES— was never imported anywhereTHEME_CLASSES— was never imported anywhereBODY_MODE_CLASSES— was never imported anywhere
Single source of truth: src/core/system/appearance/themeRegistry.ts
| Metric | Phase 2 | Phase 3 | Delta |
|---|---|---|---|
| Main JS (gzip) | 626.0 kB | 626.9 kB | +0.9 kB |
| Main CSS (gzip) | 12.24 kB | 13.53 kB | +1.29 kB |
JS increase: TopBar component + DesktopRuntime changes.
CSS increase: system-bars.css (new), AppSwitcher token updates.
None.
- Legacy
app.css(1463 lines) still contains old Taskbar rules — functional but redundant withsystem-bars.css - Weather surface is a placeholder (no real API)
- Search surface has no backend integration
BottomBarcomponent exists but is not rendered (Taskbar handles the bottom bar directly)- Theme cycling in Taskbar still uses internal state — could migrate to appearance module fully
- Implement real weather provider (extensible architecture)
- Connect search surface to actual search functionality
- Begin StartMenu visual evolution
- Consider BottomBar/Taskbar unification
- Add notification system to BottomBar right zone
- Migrate remaining legacy
app.cssrules to Fluent Valley tokens
Goal: Reduce legacy dependency, enforce surface hierarchy, refine window visuals.
| Category | Lines | Description |
|---|---|---|
| ACTIVE | ~250 | Core window, loader, background, start menu, window states |
| COMPATIBILITY | ~600 | Legacy theme taskbar/window/menu styles (Win95, WinXP, macOS, Ubuntu) |
| DUPLICATE removed | ~185 | App switcher theme styles (now in themes.css + AppSwitcher.css) |
| DEAD removed | ~95 | search-bar, mobile-search-icon, taskbar-separator, .window.moved, .window.blocked, compatibility-error, fadeIn keyframe |
Legacy CSS: 1463 → 1059 lines (-404 lines, -27.6%)
No files were moved. Dead and duplicate selectors were removed from legacy/app.css. Active selectors remain in place.
system-bars.css expanded with:
- Window surface tokens (semantic background, elevation, border, transitions)
- OnerOS 2026 window surface overrides
- Interaction consistency section (StartMenu, context menu, window action transitions)
- Window focus-visible ring
prefers-reduced-motionfor window transitions
*universal reset (duplicate of globals/reset.css)bodybase styles (duplicate of globals/base.css)body.margin(duplicate)#os-background.opacity(dead).taskbar-separatorbase + all theme variants (dead — not in DOM).apps .search-bar input,.apps .mobile-search-icon(dead).window.moved,.window.blocked(dead)- Empty
.actions .action-minimize,.actions .action-closerules - All
.app-switcher-overlay,.app-switcher,.app-switcher .appbase rules (duplicate) - Win95/WinXP/macOS/Ubuntu
.app-switchertheme rules (duplicate — in themes.css) .app-switcher-icon,.close-switcher(dead)compatibility-error(dead)@keyframes fadeIn(duplicate offv-fade-in)- Responsive
.app-switcherrules in 640px query (duplicate) - Dead
.search-bar,.mobile-search-icon,.mobile-hiddenresponsive rules
All legacy theme taskbar/window/menu styles remain:
#os-taskbar.win95-theme+ children#os-taskbar.winxp-theme+ children#os-taskbar.macos-theme+ children#os-taskbar.ubuntu-theme+ childrenbody.win95-mode .window+ childrenbody.winxp-mode .window+ childrenbody.macos-mode .window+ childrenbody.ubuntu-mode .window+ children- StartMenu layout classes (
.menu-layout,.app-tile,.menu-elm)
- Background: Uses
--fv-surface-elevatedsemantic token - Border: Uses
--fv-border-subtlefor inactive,--color-accentfor active - Elevation:
--fv-elevation-2(resting) →--fv-elevation-3(active) - Title bar: Uses
--fv-surface-elevated, subtle bottom border - Transitions:
--fv-transition-normalfor shadow,--fv-transition-fastfor border - OnerOS 2026: 12px radius, softer shadows, accent-colored active border
- WindowManager behavior: untouched
- StartMenu
.app-tileand.menu-elm: background + color transitions - Context menu items: background transition
- Window action buttons: background + scale(0.92) on press
- All transitions use
--fv-transition-fast prefers-reduced-motion: reducedisables all transitions
All 7 themes verified functional:
- Modern (0): FV window tokens apply
- Centered (1): FV window tokens apply
- Win95 (2): Legacy window chrome overrides FV tokens
- WinXP (3): Legacy window chrome overrides FV tokens
- macOS (4): Legacy window chrome overrides FV tokens
- Ubuntu (5): Legacy window chrome overrides FV tokens
- OnerOS 2026 (6): FV window tokens with theme-specific values
| Metric | Before (Phase 3) | After (Phase 4) | Delta |
|---|---|---|---|
| Legacy CSS lines | 1463 | 1059 | -404 lines |
| System CSS lines | 614 | 695 | +81 lines |
| Main CSS (gzip) | 13.53 kB | 12.93 kB | -0.60 kB |
| Metric | Phase 3 | Phase 4 | Delta |
|---|---|---|---|
| Main JS (gzip) | 626.9 kB | 626.9 kB | 0 |
| Main CSS (gzip) | 13.53 kB | 12.93 kB | -0.60 kB |
CSS decreased due to removal of dead/duplicate selectors.
0 warnings.
None found. All themes functional. Windows open/close/focus/drag/resize/maximize work. Taskbar, StartMenu, AppSwitcher, context menus all work. Mobile layout works.
- Legacy
app.cssstill 1059 lines (compatibility layer for themes) - Weather/Search surfaces are placeholders
BottomBarcomponent exists but Taskbar handles bottom bar directly- Theme cycling still uses Taskbar internal state
- StartMenu visual evolution
- Search backend integration
- Real weather provider
- Notification system
- BottomBar/Taskbar unification
- Further legacy CSS reduction as themes are modernized
Goal: Improve desktop experience — taskbar states, window transitions, microinteractions.
taskbarState.ts— derives app state from WindowManager data (no duplicate state)deriveTaskbarStates()groups windows byappId, computesisOpen/isFocused/isMinimized/windowCountgetBestWindowForApp()finds best window for focus/restore
--open: subtle background--focused: accent underline indicator--minimized: dimmed + gray underline
- Open:
scale(0.96) + opacity 0→scale(1) + opacity 1(200ms) - Close:
scale(1) + opacity 1→scale(0.96) + opacity 0(100ms) +pointer-events: none - Minimize:
scale(0.8) + translateY(20px) + opacity 0(100ms) - Restore:
scale(0.8) + translateY(20px) + opacity 0→scale(1) + opacity 1(200ms)
All reused: --fv-duration-fast/normal, --fv-ease-standard/decelerate/accelerate. No new tokens.
prefers-reduced-motion: reduce disables all transitions and animations.
| Metric | Phase 4 | Phase 5 | Delta |
|---|---|---|---|
| JS (gzip) | 626.9 kB | 641.4 kB | +14.5 kB |
| CSS (gzip) | 12.93 kB | 13.2 kB | +0.27 kB |
Goal: Connect App Registry metadata to Taskbar, icon resolver, pinned apps, race condition fix.
src/core/apps/iconResolver.ts— single source of truth for icon mappingresolveAppIcon(iconString)→ FontAwesomeIconProp- Used by Taskbar, AppSwitcher, and any future consumer
- Safe fallback for unknown icons
- No type changes needed — all 12 apps already have
iconfield in registry
| App | Icon |
|---|---|
| Settings | fa-gear |
| Personalization | fa-palette |
| fa-globe | |
| fa-facebook | |
| Bing | fa-magnifying-glass |
| Calculator | fa-calculator |
| MPlayer | fa-music |
| Linux Mode | fa-terminal |
| DevZone | fa-code |
| WinSync | fa-rotate |
| KDialer | fa-phone |
| Tools | fa-screwdriver-wrench |
src/core/system/preferences/taskbarPreferences.tsDEFAULT_PINNED_APPS:['google', 'facebook', 'bing']loadPinnedApps()/savePinnedApps()/validatePinnedApps()pinApp()/unpinApp()/isPinned()- Validation: removes unknown IDs, duplicates, preserves order, fallback to defaults
- Persisted in
localStorageviaos_pinned_appskey
- Loads pinned apps from preferences module
- Resolves icons from App Registry via iconResolver
- Each window instance rendered as individual button (not grouped by app)
- Open non-pinned apps also appear as individual buttons
- Replaced local
ICON_MAPwith sharediconResolver - Resolves icons from
window.iconor AppRegistry - Filters out closing windows (
isClosing) - Context menu: app icon in title + "Switch to this app" / "Move Window" / "Close app"
- Still uses hardcoded tiles (planned for Phase 7)
- Icons remain hardcoded per-tile
- Every window instance renders as its own taskbar button
- Each button shows its specific window state (focused/minimized/open)
windowCountno longer used for visual grouping
- Added
isClosingtoWindowDatatype closeWindow()marks window asisClosing: truefirst, removes after 120ms- Single-instance lookup excludes
isClosingwindows - Prevents ghost windows during rapid close/reopen
- Right-click any taskbar icon shows context menu
- App icon + name in title
- "Open new instance" / "Close app"
- Positioned above taskbar (
bottom: 52px)
- Inactive windows show transparent click blocker overlay (
z-index: 10) - First click focuses the window, second click goes to iframe
- Header bar (title, close/min/max) always clickable (
z-index: 11) isActive = windowData.isFocused === true— only explicitly focused windows allow iframe clicks
| Metric | Phase 5 | Phase 6 | Delta |
|---|---|---|---|
| JS (gzip) | 641.4 kB | 643.5 kB | +2.1 kB |
| CSS (gzip) | 13.2 kB | 13.4 kB | +0.2 kB |
None.
- StartMenu still hardcoded (not using App Registry)
- No drag-to-reorder pinned apps
- Weather/Search surfaces are placeholders
- Theme cycling still uses Taskbar internal state
- BottomBar component exists but unused
- StartMenu visual evolution using App Registry
- Per-app icon in StartMenu tiles
- Drag-to-reorder pinned apps
- Search backend integration
- Real weather provider
- Notification system
Goal: Replace legacy system surfaces with modern Fluent Valley components.
- Rewritten with App Registry integration — no hardcoded app list
getAllApps()→ display all registered apps with resolved icons- Built-in search bar with keyboard navigation
- Footer: Personalization / Settings / Power
- Glass surface with
--fv-surface-glasstokens
src/core/system/search/— types, utils, indexsearchSystem(query, openWindow) → SearchResult[]- Searches App Registry by name, description, category, id
- TopBar SearchSurface uses real search with dropdown results
- Keyboard: ArrowUp/Down/Enter/Escape
- Future-ready for commands, files, settings
src/core/system/weather/— types, service, indexWeatherProviderinterface (swappable)WeatherServicewith localStorage caching (30min TTL)- Graceful fallback: time-based weather display
- No API keys in code
src/core/system/notifications/— types, store, components- Store:
subscribeNotifications(),notify(),dismissNotification(),clearNotifications() - Reactive subscriber pattern (no external state library)
NotificationBellin Taskbar with unread badgeNotificationPanel: glass surface, dismiss, clear all, empty state- Type icons: info/success/warning/error
| Metric | Phase 6 | Phase 7 | Delta |
|---|---|---|---|
| JS (gzip) | 643.5 kB | 644.9 kB | +1.4 kB |
| CSS (gzip) | 13.4 kB | 14.8 kB | +1.4 kB |
- Real weather API integration
- Drag-to-reorder pinned apps
- User-configurable StartMenu pins
- Desktop widget system
- System command palette
- Multi-monitor support
Goal: Final release-readiness pass for OnerOS Web Preview 3.1.0 Fluent Valley.
| File | Purpose |
|---|---|
src/core/system/appearance/themeRegistry.ts |
Theme registry (single source of truth) |
src/core/system/appearance/accent.ts |
Accent color CSS variable management |
src/core/system/appearance/appearance.ts |
Appearance service (theme, accent, wallpaper) |
src/core/system/appearance/index.ts |
Barrel exports |
src/core/system/search/search.types.ts |
SearchResult type |
src/core/system/search/search.utils.ts |
searchSystem() |
src/core/system/search/index.ts |
Barrel |
src/core/system/weather/weather.types.ts |
WeatherData types |
src/core/system/weather/weather.service.ts |
WeatherService with caching |
src/core/system/weather/index.ts |
Barrel |
src/core/system/notifications/notification.types.ts |
SystemNotification type |
src/core/system/notifications/notificationStore.ts |
Reactive notification store |
src/core/system/notifications/index.ts |
Barrel |
src/core/system/surfaces/Notifications/NotificationBell.tsx |
Bell + badge |
src/core/system/surfaces/Notifications/NotificationPanel.tsx |
Panel |
src/core/system/surfaces/Taskbar/taskbarState.ts |
Taskbar state derivation |
src/core/apps/iconResolver.ts |
Shared icon mapping |
src/core/system/preferences/taskbarPreferences.ts |
Pinned apps persistence |
src/styles/tokens/motion.css |
Motion system |
src/styles/tokens/surfaces.css |
Surface hierarchy + glass |
src/styles/system-bars.css |
System bar styling |
src/styles/system-surfaces.css |
StartMenu, Search, Notifications |
src/styles/themes/oneros2026.css |
OnerOS 2026 theme |
| File | Changes |
|---|---|
| All token files | Fluent Valley semantic tokens |
| All theme files | Theme-specific surface overrides |
src/core/windowManager/ |
Snap, layout state, API additions |
src/core/system/surfaces/Taskbar/ |
Complete rewrite with app states |
src/core/system/surfaces/AppSwitcher/ |
Context menu, icons |
src/core/system/surfaces/StartMenu/ |
Rewrite with App Registry |
src/core/system/topbar/TopBar.tsx |
Weather, search, auto-hide |
src/core/desktop/DesktopRuntime.tsx |
TopBar, snap APIs |
src/core/desktop/layers/SystemSurfaceLayer.tsx |
Full viewport |
src/apps/personalization/ |
Appearance module integration |
src/apps/settings/settings.jsx |
Advanced section, version |
src/apps/linux-mode/linuxmode.jsx |
Appearance module |
| File | Reason |
|---|---|
src/core/system/surfaces/SystemBar/ |
Dead component (never used) |
src/core/system/bottombar/ |
Dead component (Taskbar used instead) |
src/components/ui/ |
Dead components (AppShell, Panel, etc.) |
src/OS/*.js bridges |
Dead compatibility bridges |
| Various barrel files | Cleaned dead exports |
- Timer cleanup: Taskbar hideTimeoutRef unmount cleanup
- Hardcoded colors → CSS variables in legacy app.css
- Dead code removal: 20+ files removed
- Barrel exports cleaned
pointer-events: autoon AppSwitcher overlay- Window iframe click blocker (
isFocused === true) - focusWindow DOM
.activeclass sync - minimizeWindow properly hides window (
display: none)
- All 7 themes define complete accent variant tokens
clearInlineAccentStyles()properly cleans for locked themes- OnerOS 2026 properly scoped with
body.oneros2026-mode - Legacy themes properly scoped with body class selectors
| Metric | v3.0 (start) | v3.1 (final) | Delta |
|---|---|---|---|
| JS (gzip) | 656.64 kB | 647.7 kB | -8.9 kB |
| CSS (gzip) | ~10.35 kB | 16.5 kB | +6.15 kB |
| Legacy CSS lines | 1463 | 1060 | -403 lines |
OnerOS Web Preview 3.1.0 Fluent Valley is feature-complete, stable, and ready for publication.
All 7 themes functional. 15 applications registered. No new dependencies. Zero build errors. Zero warnings.
Goal: Interactive Quick Panels for Clock and Weather in the TopBar.
TopBar
├── WeatherSurface → click → WeatherPanel
├── SearchSurface (unchanged)
└── Clock trigger → click → ClockPanel
QuickPanel (shared)
├── positioning via usePanelPosition hook
├── outside click → close
├── Escape → close
├── mutual exclusivity (one panel at a time)
└── Fluent Valley surface tokens
| File | Purpose |
|---|---|
src/core/system/quickPanels/QuickPanel.tsx |
Shared panel + usePanelPosition hook |
src/core/system/quickPanels/ClockPanel/ClockPanel.tsx |
Clock panel (HH:mm:ss, date, day) |
src/core/system/quickPanels/WeatherPanel/WeatherPanel.tsx |
Weather details panel |
src/core/system/quickPanels/index.ts |
Barrel exports |
| File | Changes |
|---|---|
src/core/system/topbar/TopBar.tsx |
Clock/weather clickable, panels integrated |
src/core/system/weather/weather.types.ts |
Added humidity, wind, feelsLike |
src/styles/system-surfaces.css |
Panel + clock + weather CSS |
src/styles/system-bars.css |
Trigger hover styles |
src/styles/themes.css |
Legacy theme panel overrides |
src/styles/themes/oneros2026.css |
OnerOS 2026 panel styling |
- HH:mm:ss, seconds update every second
- Full date + day of week
- Localized via Intl.DateTimeFormat
- Reuses WeatherService cache
- Icon, temperature, location, condition
- Optional: humidity, wind
- Loading/error states
| Metric | Before | After | Delta |
|---|---|---|---|
| JS (gzip) | 647.7 kB | 648.7 kB | +1.0 kB |
| CSS (gzip) | 16.5 kB | 17.0 kB | +0.5 kB |