About
diff --git a/apps/web/src/store/index.ts b/apps/web/src/store/index.ts
index 810bf7f..ea194f2 100644
--- a/apps/web/src/store/index.ts
+++ b/apps/web/src/store/index.ts
@@ -3,7 +3,9 @@ export { useDownloadProgressStore } from "./slices/downloadProgressSlice";
export { useJobResultsStore } from "./slices/jobResultsSlice";
export { useUIStore } from "./slices/uiSlice";
export { useSSEStore } from "./slices/sseSlice";
+export { useBigPictureStore } from "./slices/bigPictureSlice";
export type { SpeedDataPoint, DownloadProgressState, SSEState, JobResultsState, UIState } from "./types";
+export type { BigPictureState, BigPictureStore } from "./slices/bigPictureSlice";
diff --git a/apps/web/src/store/slices/bigPictureSlice.ts b/apps/web/src/store/slices/bigPictureSlice.ts
new file mode 100644
index 0000000..c012941
--- /dev/null
+++ b/apps/web/src/store/slices/bigPictureSlice.ts
@@ -0,0 +1,160 @@
+import { create } from "zustand";
+import { persist } from "zustand/middleware";
+
+export type GamepadButtonName =
+ | "A" | "B" | "X" | "Y"
+ | "LB" | "RB" | "LT" | "RT"
+ | "SELECT" | "START"
+ | "L3" | "R3"
+ | "UP" | "DOWN" | "LEFT" | "RIGHT";
+
+export type GamepadAction =
+ | "SELECT"
+ | "BACK"
+ | "DETAILS"
+ | "MENU"
+ | "PAGE_UP"
+ | "PAGE_DOWN"
+ | "SCROLL_UP"
+ | "SCROLL_DOWN"
+ | "NAVIGATE_UP"
+ | "NAVIGATE_DOWN"
+ | "NAVIGATE_LEFT"
+ | "NAVIGATE_RIGHT";
+
+export type ButtonMappingConfig = Record;
+
+// Default button mapping (Xbox/PlayStation standard)
+const DEFAULT_BUTTON_MAPPING: ButtonMappingConfig = {
+ A: "SELECT", // Confirm/Select
+ B: "BACK", // Back/Cancel
+ X: "DETAILS", // Show details
+ Y: "MENU", // Open menu
+ LB: "PAGE_UP", // Previous page
+ RB: "PAGE_DOWN", // Next page
+ LT: "SCROLL_UP", // Scroll up
+ RT: "SCROLL_DOWN", // Scroll down
+ SELECT: "MENU", // Menu
+ START: "MENU", // Menu
+ L3: "SELECT", // Confirm
+ R3: "DETAILS", // Details
+ UP: "NAVIGATE_UP", // Navigate up
+ DOWN: "NAVIGATE_DOWN", // Navigate down
+ LEFT: "NAVIGATE_LEFT", // Navigate left
+ RIGHT: "NAVIGATE_RIGHT" // Navigate right
+};
+
+export interface BigPictureState {
+ enabled: boolean;
+ buttonMapping: ButtonMappingConfig;
+ hapticFeedbackEnabled: boolean;
+ deadzone: number;
+ selectedMonitor: number;
+ showOnScreenKeyboard: boolean;
+ keyboardLayout: "qwerty" | "azerty" | "dvorak";
+ gridSize: "small" | "medium" | "large" | "auto";
+ autoHideUI: boolean;
+ autoHideDelay: number; // in seconds
+ availableMonitors: number; // Number of detected monitors
+}
+
+type BigPictureActions = {
+ setEnabled: (enabled: boolean) => void;
+ setButtonMapping: (mapping: ButtonMappingConfig) => void;
+ resetButtonMapping: () => void;
+ setHapticFeedbackEnabled: (enabled: boolean) => void;
+ setDeadzone: (deadzone: number) => void;
+ setSelectedMonitor: (monitor: number) => void;
+ setShowOnScreenKeyboard: (show: boolean) => void;
+ setKeyboardLayout: (layout: "qwerty" | "azerty" | "dvorak") => void;
+ setGridSize: (size: "small" | "medium" | "large" | "auto") => void;
+ setAutoHideUI: (autoHide: boolean) => void;
+ setAutoHideDelay: (delay: number) => void;
+ setAvailableMonitors: (count: number) => void;
+ detectMonitors: () => Promise;
+};
+
+export type BigPictureStore = BigPictureState & BigPictureActions;
+
+const initialState: BigPictureState = {
+ enabled: false,
+ buttonMapping: DEFAULT_BUTTON_MAPPING,
+ hapticFeedbackEnabled: true,
+ deadzone: 0.25,
+ selectedMonitor: 0,
+ showOnScreenKeyboard: false,
+ keyboardLayout: "qwerty",
+ gridSize: "auto",
+ autoHideUI: false,
+ autoHideDelay: 3,
+ availableMonitors: 1
+};
+
+export const useBigPictureStore = create()(
+ persist(
+ (set) => ({
+ ...initialState,
+
+ setEnabled: (enabled) => set({ enabled }),
+
+ setButtonMapping: (mapping) => set({ buttonMapping: mapping }),
+
+ resetButtonMapping: () => set({ buttonMapping: DEFAULT_BUTTON_MAPPING }),
+
+ setHapticFeedbackEnabled: (enabled) => set({ hapticFeedbackEnabled: enabled }),
+
+ setDeadzone: (deadzone) => set({ deadzone }),
+
+ setSelectedMonitor: (monitor) => set({ selectedMonitor: monitor }),
+
+ setShowOnScreenKeyboard: (show) => set({ showOnScreenKeyboard: show }),
+
+ setKeyboardLayout: (layout) => set({ keyboardLayout: layout }),
+
+ setGridSize: (size) => set({ gridSize: size }),
+
+ setAutoHideUI: (autoHide) => set({ autoHideUI: autoHide }),
+
+ setAutoHideDelay: (delay) => set({ autoHideDelay: delay }),
+
+ setAvailableMonitors: (count) => set({ availableMonitors: count }),
+
+ detectMonitors: async () => {
+ // Use Screen Orientation API if available
+ if (window.screen && 'isExtended' in window.screen) {
+ try {
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ const isExtended = await (window.screen as any).isExtended?.();
+ if (isExtended) {
+ // Multi-monitor setup detected
+ // We can't get exact count, but we know there's more than one
+ set({ availableMonitors: 2 });
+ } else {
+ set({ availableMonitors: 1 });
+ }
+ } catch {
+ // If the API call fails, assume single monitor
+ set({ availableMonitors: 1 });
+ }
+ } else {
+ // Fallback: assume single monitor
+ set({ availableMonitors: 1 });
+ }
+ }
+ }),
+ {
+ name: "crocdesk-bigpicture-storage",
+ partialize: (state) => ({
+ enabled: state.enabled,
+ buttonMapping: state.buttonMapping,
+ hapticFeedbackEnabled: state.hapticFeedbackEnabled,
+ deadzone: state.deadzone,
+ selectedMonitor: state.selectedMonitor,
+ keyboardLayout: state.keyboardLayout,
+ gridSize: state.gridSize,
+ autoHideUI: state.autoHideUI,
+ autoHideDelay: state.autoHideDelay
+ })
+ }
+ )
+);
diff --git a/docs/BIG_PICTURE_MODE.md b/docs/BIG_PICTURE_MODE.md
new file mode 100644
index 0000000..dcbb13d
--- /dev/null
+++ b/docs/BIG_PICTURE_MODE.md
@@ -0,0 +1,195 @@
+# Big Picture Mode
+
+Big Picture Mode is a controller-friendly, full-screen interface designed for TVs and couch gaming. It provides an immersive experience for browsing and managing your ROM collection with Xbox and PlayStation controllers.
+
+## Features
+
+### Controller Support
+- **Xbox Controllers**: Full support for Xbox 360, Xbox One, and Xbox Series X/S controllers
+- **PlayStation Controllers**: Full support for DualShock 4 and DualSense controllers
+- **Haptic Feedback**: Vibration feedback for button presses and navigation (when supported)
+- **Button Remapping**: Customize button mappings to your preference
+
+### Navigation
+- **D-Pad/Left Stick**: Navigate through the game grid
+- **A Button (✕ on PlayStation)**: Select game or confirm action
+- **B Button (○ on PlayStation)**: Go back or cancel
+- **X Button (□ on PlayStation)**: Open search
+- **Y Button (△ on PlayStation)**: Open menu
+- **LB/RB (L1/R1)**: Navigate between pages
+- **START Button**: Open menu
+
+### UI Features
+- **Dynamic Grid Sizing**: Automatically adjusts grid layout based on screen resolution
+- **On-Screen Keyboard**: Full keyboard for text input without needing a physical keyboard
+- **Search**: Find games quickly with controller-friendly search
+- **Downloads View**: Monitor active downloads with progress bars
+- **Fullscreen Mode**: Automatic fullscreen for distraction-free gaming
+- **Multi-Monitor Support**: Choose which monitor to display Big Picture Mode on
+
+## Getting Started
+
+### Accessing Big Picture Mode
+
+1. **From Settings Page**:
+ - Navigate to Settings
+ - Scroll to "Big Picture Mode" section
+ - Click "🎮 Launch Big Picture Mode"
+
+2. **Direct URL**:
+ - Navigate to `/big-picture` in your browser
+
+### Controller Setup
+
+Big Picture Mode automatically detects connected controllers. Simply:
+
+1. Connect your Xbox or PlayStation controller to your PC
+2. Launch Big Picture Mode
+3. Start navigating with your controller
+
+The controller will be detected automatically, and you'll see haptic feedback when you press buttons (if your controller supports it).
+
+### Configuration
+
+#### Haptic Feedback
+Enable or disable controller vibration:
+- Go to Settings → Big Picture Mode
+- Toggle "Enable haptic feedback (controller vibration)"
+
+#### Grid Size
+Adjust the number of games displayed in the grid:
+- **Auto**: Dynamic sizing based on screen resolution (recommended)
+- **Small**: 3 columns
+- **Medium**: 4 columns
+- **Large**: 5 columns
+
+#### Multi-Monitor Setup
+If you have multiple monitors:
+1. Big Picture Mode will automatically detect them
+2. Go to Settings → Big Picture Mode → Monitor Selection
+3. Choose your preferred monitor
+
+## Controls Reference
+
+### Main Screen (Browse Games)
+
+| Action | Xbox | PlayStation | Keyboard |
+|--------|------|-------------|----------|
+| Navigate | D-Pad / Left Stick | D-Pad / Left Stick | Arrow Keys |
+| Select Game | A | ✕ (Cross) | Enter |
+| Go Back | B | ○ (Circle) | Escape |
+| Search | X | □ (Square) | S |
+| Menu | Y / START | △ (Triangle) / OPTIONS | M |
+| Previous Page | LB | L1 | Page Up |
+| Next Page | RB | R1 | Page Down |
+
+### On-Screen Keyboard
+
+| Action | Xbox | PlayStation | Keyboard |
+|--------|------|-------------|----------|
+| Navigate Keys | D-Pad / Left Stick | D-Pad / Left Stick | Arrow Keys |
+| Select Key | A | ✕ (Cross) | Enter / Space |
+| Close Keyboard | B | ○ (Circle) | Escape |
+
+### Downloads View
+
+| Action | Xbox | PlayStation | Keyboard |
+|--------|------|-------------|----------|
+| Navigate | D-Pad Up/Down | D-Pad Up/Down | Arrow Keys |
+| Go Back | B / START | ○ (Circle) / OPTIONS | Escape |
+
+## Menu Options
+
+Press Y (△ on PlayStation) or START to open the menu:
+
+- **Browse Games**: Return to main Big Picture browse view
+- **Library**: View your local game library
+- **Downloads**: View active downloads
+- **Queue**: View job queue
+- **Settings**: Access application settings
+- **Exit Big Picture**: Return to standard desktop mode
+
+## Tips & Tricks
+
+1. **Analog Stick Sensitivity**: If navigation feels too sensitive, adjust the deadzone in settings
+2. **Search Optimization**: Use the on-screen keyboard with D-Pad for precise navigation
+3. **Page Navigation**: Use LB/RB (L1/R1) to quickly jump between pages
+4. **Haptic Feedback**: Different intensities indicate different actions (light for navigation, medium for selection, heavy for controller connection)
+5. **Fullscreen Toggle**: Press F11 to manually toggle fullscreen if needed
+
+## Troubleshooting
+
+### Controller Not Detected
+1. Ensure your controller is properly connected
+2. For wireless controllers, make sure they're paired
+3. Try reconnecting the controller
+4. Check browser console for gamepad connection messages
+
+### Haptic Feedback Not Working
+- Some controllers (especially older models) may not support vibration
+- Check that haptic feedback is enabled in Settings
+- Try a different USB port or wireless receiver
+
+### Navigation Feels Unresponsive
+- Adjust the deadzone setting in Big Picture Mode settings
+- Try using D-Pad instead of analog stick for more precise control
+- Ensure no other applications are capturing controller input
+
+### Multi-Monitor Issues
+1. Ensure you've selected the correct monitor in settings
+2. Restart Big Picture Mode after changing monitor selection
+3. Some browsers may not fully support multi-monitor APIs
+
+## Performance Optimization
+
+Big Picture Mode includes several optimizations:
+
+- **Virtual Scrolling**: Only renders visible game cards for better performance
+- **Image Lazy Loading**: Loads cover art on-demand as you scroll
+- **Debounced Navigation**: Prevents input overload during rapid navigation
+- **Request Animation Frame**: Uses RAF for smooth 60fps controller polling
+
+## Accessibility
+
+While Big Picture Mode is designed for controllers, it remains fully accessible:
+
+- **Keyboard Support**: All controller actions have keyboard equivalents
+- **Focus Indicators**: Clear visual feedback shows currently selected items
+- **High Contrast**: Works well with both light and dark themes
+- **Screen Reader Friendly**: Semantic HTML structure for screen reader compatibility
+
+## Browser Support
+
+Big Picture Mode uses modern web APIs:
+
+- **Gamepad API**: For controller support (Chrome 21+, Firefox 29+, Safari 10.1+)
+- **Fullscreen API**: For immersive experience (All modern browsers)
+- **Vibration Actuator API**: For haptic feedback (Chrome 68+, experimental in others)
+
+For the best experience, we recommend:
+- **Chrome/Edge**: Full support for all features including haptic feedback
+- **Firefox**: Full support except vibration may be limited
+- **Safari**: Basic controller support, limited haptic feedback
+
+## Future Enhancements
+
+Planned improvements for Big Picture Mode:
+
+- [ ] Analog stick scrolling support
+- [ ] Advanced button remapping UI
+- [ ] Voice control integration
+- [ ] Achievement notifications
+- [ ] Friend presence indicators
+- [ ] Cloud save status
+- [ ] Quick launch from Big Picture Mode
+
+## Contributing
+
+Found a bug or have a feature request? Please open an issue on GitHub:
+https://github.com/luandev/jacare/issues
+
+When reporting controller issues, please include:
+- Controller model and brand
+- Connection type (USB/Bluetooth)
+- Operating system
+- Browser and version