diff --git a/Lux/lux_react/src/components/AudioMixer.css b/Lux/lux_react/src/components/AudioMixer.css
index 76651880..6d3e3fc2 100644
--- a/Lux/lux_react/src/components/AudioMixer.css
+++ b/Lux/lux_react/src/components/AudioMixer.css
@@ -8,9 +8,8 @@
color: #ffffff;
font-family: 'Inter', 'Arial', sans-serif;
width: 100%;
- overflow: hidden;
- max-height: 60vh;
- overflow-y: auto;
+ overflow: visible;
+ max-height: none;
}
/* Header */
@@ -175,13 +174,10 @@
/* Frequency Bands */
.frequency-bands {
margin-bottom: 16px;
-}
-
-.frequency-bands h4 {
- margin-bottom: 15px;
- color: #fff;
- font-size: 1.2rem;
- text-align: center;
+ display: grid;
+ grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
+ gap: 12px;
+ padding: 16px;
}
.bands-grid {
@@ -491,7 +487,8 @@
.audio-mixer {
padding: 12px;
margin: 0;
- max-height: 50vh;
+ max-height: none;
+ overflow: visible;
}
.mixer-header h3 {
@@ -552,7 +549,8 @@
@media (max-width: 480px) {
.audio-mixer {
padding: 8px;
- max-height: 40vh;
+ max-height: none;
+ overflow: visible;
}
.bands-grid {
diff --git a/Lux/lux_react/src/components/ControlPanel.jsx b/Lux/lux_react/src/components/ControlPanel.jsx
index 79678d07..39db322b 100644
--- a/Lux/lux_react/src/components/ControlPanel.jsx
+++ b/Lux/lux_react/src/components/ControlPanel.jsx
@@ -11,13 +11,12 @@ import { useJenModule } from '../hooks/useJenModule.js'; // Our simple, reliable
import MediaController from "./MediaController";
import TabNavigation from "./TabNavigation";
import HomePane from "./panes/HomePane";
-import SourceImagePane from "./panes/SourceImagePane";
-import TargetImagePane from "./panes/TargetImagePane";
import BrushPane from "./panes/BrushPane";
import AudioPane from "./panes/AudioPane";
import {SceneChooserPane} from "./panes/SceneChooserPane";
import {PaneContext} from "./panes/PaneContext.jsx";
import RealtimeCamera from "./RealtimeCamera.jsx";
+import ImagePane from "./panes/ImagePane.jsx";
function ControlPanel({ dimensions, panelSize, activePane, onPaneChange }) {
const { sliderValues, onSliderChange } = React.useContext(ControlPanelContext);
@@ -244,14 +243,20 @@ function ControlPanel({ dimensions, panelSize, activePane, onPaneChange }) {
);
- case "source":
+ case "image":
return (
-
+
);
+ case "source":
case "target":
- return
;
+ // Redirect old pane values to the new unified image pane
+ return (
+
+
+
+ );
case "brush":
return
;
case "audio":
diff --git a/Lux/lux_react/src/components/MediaController.jsx b/Lux/lux_react/src/components/MediaController.jsx
index 57f94eff..3b406855 100644
--- a/Lux/lux_react/src/components/MediaController.jsx
+++ b/Lux/lux_react/src/components/MediaController.jsx
@@ -128,7 +128,6 @@ function MediaController({ isOverlay = false }) {
const syncWithBackend = () => {
if (window.module && typeof window.module.get_animation_running === 'function') {
const backendRunning = window.module.get_animation_running();
- console.log('[MediaController] Syncing with backend animation state:', backendRunning);
setIsRunning(backendRunning);
}
};
diff --git a/Lux/lux_react/src/components/TabNavigation.jsx b/Lux/lux_react/src/components/TabNavigation.jsx
index 509f7ddb..0c401e7e 100644
--- a/Lux/lux_react/src/components/TabNavigation.jsx
+++ b/Lux/lux_react/src/components/TabNavigation.jsx
@@ -82,7 +82,7 @@ function TabNavigation({ activePane, onPaneChange }) {
}
- value="source"
+ value="image"
sx={{
minHeight: '50px',
'&.Mui-selected': {
@@ -90,8 +90,8 @@ function TabNavigation({ activePane, onPaneChange }) {
background: 'rgba(25, 118, 210, 0.08)'
}
}}
- aria-label="Source Image"
- title="Source Image"
+ aria-label="Image Controls"
+ title="Image Controls"
/>
-
}
- value="target"
- sx={{
- minHeight: '50px',
- '&.Mui-selected': {
- color: 'primary.main',
- background: 'rgba(25, 118, 210, 0.08)'
- }
- }}
- aria-label="Target Image"
- title="Target Image"
- />
-
}
value="brush"
diff --git a/Lux/lux_react/src/components/panes/AudioPane.css b/Lux/lux_react/src/components/panes/AudioPane.css
index 27a6e6e4..739ed870 100644
--- a/Lux/lux_react/src/components/panes/AudioPane.css
+++ b/Lux/lux_react/src/components/panes/AudioPane.css
@@ -9,8 +9,10 @@
color: #ffffff;
font-family: 'Inter', 'Arial', sans-serif;
font-weight: 500;
- overflow: hidden;
+ overflow: visible;
transition: all 0.3s ease;
+ min-height: auto;
+ max-height: none;
}
.audio-pane.party-mode {
@@ -169,79 +171,18 @@
gap: 24px;
}
-/* Mixer Presets Container */
-.mixer-presets {
+/* Audio Control Center - Flat Layout */
+.audio-control-center {
background: rgba(255, 255, 255, 0.05);
border-radius: 16px;
padding: 20px;
border: 1px solid rgba(255, 255, 255, 0.1);
+ overflow: visible;
+ max-height: none;
+ height: auto;
}
-/* Frequency Bands Section */
-.frequency-bands {
- background: rgba(255, 255, 255, 0.08);
- border-radius: 12px;
- padding: 12px;
- margin-bottom: 16px;
- border: 1px solid rgba(255, 255, 255, 0.15);
- transition: all 0.3s ease;
-}
-
-.frequency-bands h4 {
- margin: 0 0 8px 0;
- font-weight: 700;
- font-size: 14px;
- color: #fff;
- text-shadow: 0 1px 2px rgba(0, 0, 0, 0.5);
-}
-
-/* Master Sensitivity Section */
-.master-sensitivity {
- background: rgba(255, 255, 255, 0.08);
- border-radius: 12px;
- padding: 12px;
- margin-bottom: 16px;
- border: 1px solid rgba(255, 255, 255, 0.15);
- transition: all 0.3s ease;
-}
-
-.master-sensitivity h4 {
- margin: 0 0 8px 0;
- font-weight: 700;
- font-size: 14px;
- color: #fff;
- text-shadow: 0 1px 2px rgba(0, 0, 0, 0.5);
-}
-
-/* Collapsed state - minimal space */
-.frequency-bands:has(.collapsible-header) {
- padding: 8px 12px;
- margin-bottom: 8px;
-}
-
-.master-sensitivity:has(.collapsible-header) {
- padding: 8px 12px;
- margin-bottom: 8px;
-}
-
-/* When sections are collapsed, reduce their visual footprint */
-.frequency-bands:not(:has(.simple-meters:not([style*="display: none"]))) {
- min-height: auto;
-}
-
-.master-sensitivity:not(:has(.sensitivity-content:not([style*="display: none"]))) {
- min-height: auto;
-}
-
-/* Advanced Mixer Section */
-.advanced-mixer-section {
- background: rgba(255, 255, 255, 0.08);
- border-radius: 12px;
- padding: 16px;
- border: 1px solid rgba(255, 255, 255, 0.15);
-}
-
-.advanced-mixer-section h4 {
+.audio-control-center h4 {
margin: 0 0 12px 0;
font-weight: 700;
font-size: 14px;
@@ -417,11 +358,12 @@
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.4);
}
-/* Simple Meters */
-.simple-meters {
+/* Simple Meters - Flat Style */
+.audio-control-center .simple-meters {
display: flex;
flex-direction: column;
gap: 16px;
+ margin: 16px 0;
}
.meter-row {
@@ -484,16 +426,14 @@
font-weight: 600;
}
-/* Beat Section */
-.beat-section {
+/* Beat Section - Flat Style */
+.audio-control-center .beat-section {
display: flex;
justify-content: space-between;
align-items: center;
- padding: 12px 16px;
- background: rgba(255, 255, 255, 0.08);
- border-radius: 8px;
- margin-top: 8px;
- border: 1px solid rgba(255, 255, 255, 0.15);
+ padding: 12px 0;
+ margin: 16px 0;
+ border-bottom: 1px solid rgba(255, 255, 255, 0.1);
}
.beat-indicator {
@@ -623,7 +563,7 @@
.feature-list .feature-item {
padding: 8px 12px;
- background: rgba(255, 255, 255, 0.1);
+ background: rgba(228, 163, 163, 0.1);
border-radius: 6px;
font-size: 14px;
color: #fff;
@@ -634,18 +574,28 @@
/* Mobile Responsiveness */
@media (max-width: 768px) {
.audio-pane {
- margin: 4px;
+ margin: 2px;
padding: 12px;
+ overflow: visible;
+ max-height: none;
+ }
+
+ .audio-control-center {
+ padding: 16px;
+ overflow: visible;
+ max-height: none;
}
.header-main {
flex-direction: column;
+ margin-bottom: 16px;
}
.audio-toggle,
.party-toggle {
min-width: unset;
width: 100%;
+ padding: 12px 16px;
}
.sensitivity-header {
@@ -656,6 +606,7 @@
.meter-row {
flex-direction: column;
+ gap: 8px;
}
.meter-group {
@@ -666,6 +617,7 @@
flex-direction: column;
gap: 8px;
text-align: center;
+ padding: 8px 0;
}
.party-features {
@@ -675,32 +627,97 @@
.feature-list {
grid-template-columns: 1fr;
}
+
+ /* Ensure mixer content is scrollable */
+ .mixer-content {
+ overflow: visible;
+ max-height: none;
+ }
+
+ /* Reduce spacing in collapsible sections */
+ .collapsible-header {
+ padding: 8px 4px;
+ margin-bottom: 8px;
+ }
+
+ .autoplay-controls,
+ .party-mode-info {
+ margin: 8px 0;
+ padding: 12px;
+ }
}
@media (max-width: 480px) {
.audio-pane {
- margin: 2px;
+ margin: 1px;
padding: 8px;
+ overflow: visible;
+ max-height: none;
+ }
+
+ .audio-control-center {
+ padding: 12px;
+ overflow: visible;
+ max-height: none;
+ }
+
+ .header-main {
+ gap: 8px;
+ margin-bottom: 12px;
+ }
+
+ .audio-toggle,
+ .party-toggle {
+ padding: 10px 12px;
+ font-size: 14px;
}
.viz-header {
flex-direction: column;
gap: 8px;
align-items: stretch;
+ margin-bottom: 12px;
}
.mixer-toggle {
width: 100%;
+ padding: 8px;
+ font-size: 14px;
+ }
+
+ /* Further reduce spacing for very small screens */
+ .collapsible-header {
+ padding: 6px 2px;
+ margin-bottom: 6px;
+ }
+
+ .collapsible-header h4 {
+ font-size: 13px;
+ }
+
+ .autoplay-controls,
+ .party-mode-info {
+ margin: 6px 0;
+ padding: 10px;
+ }
+
+ .simple-meters {
+ margin: 12px 0;
+ gap: 12px;
+ }
+
+ .meter-row {
+ gap: 6px;
}
}
-/* Birthday Party Mode Styles */
-.party-mode-info {
+/* Birthday Party Mode Styles - Flat */
+.audio-control-center .party-mode-info {
background: linear-gradient(135deg, rgba(255, 107, 53, 0.1) 0%, rgba(255, 138, 80, 0.1) 100%);
border: 1px solid rgba(255, 107, 53, 0.3);
- border-radius: 12px;
- padding: 16px;
- margin-top: 12px;
+ border-radius: 8px;
+ padding: 12px;
+ margin: 12px 0;
}
.party-mode-info .party-header h4 {
@@ -796,13 +813,13 @@
line-height: 1.4;
}
-/* Scene-Agnostic Autoplay Styles */
-.autoplay-controls {
+/* Scene-Agnostic Autoplay Styles - Flat */
+.audio-control-center .autoplay-controls {
background: rgba(156, 39, 176, 0.05);
border: 1px solid rgba(156, 39, 176, 0.2);
- border-radius: 12px;
- padding: 16px;
- margin-top: 12px;
+ border-radius: 8px;
+ padding: 12px;
+ margin: 12px 0;
}
.autoplay-status p {
diff --git a/Lux/lux_react/src/components/panes/AudioPane.jsx b/Lux/lux_react/src/components/panes/AudioPane.jsx
index 5b8c741f..a75bcaf7 100644
--- a/Lux/lux_react/src/components/panes/AudioPane.jsx
+++ b/Lux/lux_react/src/components/panes/AudioPane.jsx
@@ -2,9 +2,6 @@ import React, { useState, useCallback, useEffect } from 'react';
import { useAudioContext } from '../AudioContext';
import AudioMixer from '../AudioMixer';
import './AudioPane.css';
-import { Accordion, AccordionSummary, AccordionDetails } from '@mui/material';
-import { ExpandMore } from '@mui/icons-material';
-import { Typography, Box, Button } from '@mui/material';
import { HiMicrophone } from 'react-icons/hi';
import { FaMicrophoneSlash } from "react-icons/fa6";
@@ -21,16 +18,11 @@ const AudioPane = () => {
handleMixerGainChange
} = useAudioContext();
- // Party mode state
const [partyMode, setPartyMode] = useState(true); // Default ON for birthday celebration
- const [mixerExpanded, setMixerExpanded] = useState(false);
- const [showAdvanced, setShowAdvanced] = useState(false);
+ const [mixerExpanded, setMixerExpanded] = useState(true); // Default expanded since mixer is primary control
- // Collapsible sections for advanced view
const [showFrequencyBands, setShowFrequencyBands] = useState(false);
- const [showMasterSensitivity, setShowMasterSensitivity] = useState(false);
const [showMixerPresets, setShowMixerPresets] = useState(true);
- const [showIntegrationStatus, setShowIntegrationStatus] = useState(false);
// Integration status state
const [integrationStatus, setIntegrationStatus] = useState(null);
@@ -91,11 +83,6 @@ const AudioPane = () => {
// The useEffect will handle sensitivity changes based on the new party mode state
};
- const handleSensitivityChange = useCallback((value) => {
- console.log(`ποΈ Sensitivity changed to: ${value}%`);
- setSensitivity(value / 100); // Convert percentage to decimal
- }, [setSensitivity]);
-
const handleFrequencyBandConfig = useCallback((config) => {
console.log('ποΈ Frequency band config updated:', config);
if (config.gains && handleMixerGainChange) {
@@ -112,10 +99,6 @@ const AudioPane = () => {
console.log('ποΈ Mixer state changed:', mixerState);
}, []);
- // Convert sensitivity from decimal to percentage for display
- const sensitivityPercentage = Math.round(sensitivity * 100);
- const maxSensitivity = 200; // 0-200% range for all modes
-
// Enhanced integration status check
const checkIntegrationStatus = useCallback(() => {
if (!window.module) return;
@@ -140,8 +123,6 @@ const AudioPane = () => {
}
}, []);
- // Autoplay control handlers
- const [autoplayIntensity, setAutoplayIntensity] = useState(0.002);
const handleToggleAutoplay = useCallback(() => {
if (!window.module || !window.module.enable_scene_autoplay) return;
@@ -160,22 +141,6 @@ const AudioPane = () => {
}
}, [integrationStatus?.autoplay_active, checkIntegrationStatus]);
- const handleIntensityChange = useCallback((e) => {
- const intensity = parseFloat(e.target.value);
- setAutoplayIntensity(intensity);
-
- if (window.module && window.module.set_autoplay_intensity) {
- try {
- const success = window.module.set_autoplay_intensity(intensity);
- if (success) {
- console.log(`π² Autoplay intensity set to: ${intensity}`);
- }
- } catch (error) {
- console.error('π² β Error setting autoplay intensity:', error);
- }
- }
- }, []);
-
return (
{/* Mobile-First Header */}
@@ -190,149 +155,79 @@ const AudioPane = () => {
{isEnabled ? : }
-
-