diff --git a/src/App.tsx b/src/App.tsx index 4bbbab7..632346c 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -4,7 +4,7 @@ import { useState } from 'react'; import './styles/App.css'; import { DSP, DSPStatus, AppPage } from './types/types'; import TopBar from './components/topbar/Topbar'; -import DSPPage from './pages/DspPage'; +import DSPPage from './pages/DspPage/DspPage'; import AddDSPForm from './pages/AddDspPage'; import { useNotifications } from './hooks/useNotifications'; import Notifications from './components/Notifications/Notifications'; diff --git a/src/components/Button/Button.css b/src/components/Button/Button.css index f851af5..5dd8892 100644 --- a/src/components/Button/Button.css +++ b/src/components/Button/Button.css @@ -78,3 +78,14 @@ border-color: var(--accent-down); color: var(--text-primary); } + +.btn-outline { + background: transparent; + border-color: var(--border-hairline); + color: var(--text-muted); +} + +.btn-outline:hover:not(:disabled) { + color: var(--text-primary); + border-color: var(--text-muted); +} diff --git a/src/components/Button/Button.tsx b/src/components/Button/Button.tsx index f4a75f7..f9d2186 100644 --- a/src/components/Button/Button.tsx +++ b/src/components/Button/Button.tsx @@ -70,17 +70,22 @@ export default function Button({ }, [fontSize, children, W]); const button = ( - - ); + +); if (!scale) return button; diff --git a/src/components/dsp408/ConnectionPanel.tsx b/src/components/dsp408/ConnectionPanel.tsx deleted file mode 100644 index da6fb89..0000000 --- a/src/components/dsp408/ConnectionPanel.tsx +++ /dev/null @@ -1,69 +0,0 @@ -import { DSP } from '../../types/types'; - -function ConnectionPanel({ - dsp, - onConnect, - onDisconnect, -}: { - dsp: DSP; - onConnect: () => void; - onDisconnect: () => void; -}) { - const statusLabel = - dsp.status === 'connected' - ? 'Connected' - : dsp.status === 'connecting' - ? 'Connecting…' - : 'Disconnected'; - - return ( -
-
-
-

{dsp.name}

-
{dsp.type}
-
- -
- - {statusLabel} -
-
- -
-
-
IP address
-
{dsp.ip}
-
- -
-
Port
-
{dsp.port}
-
- -
-
Device ID
-
{dsp.deviceId || '—'}
-
-
- -
- {dsp.status === 'connected' ? ( - - ) : ( - - )} -
-
- ); -} - -export default ConnectionPanel; diff --git a/src/components/dsp408/ConnectionSection/ConnectionSection.css b/src/components/dsp408/ConnectionSection/ConnectionSection.css new file mode 100644 index 0000000..161c510 --- /dev/null +++ b/src/components/dsp408/ConnectionSection/ConnectionSection.css @@ -0,0 +1,62 @@ +.connection-panel-frame { + width: 33.333%; + height: 33.333%; + box-sizing: border-box; +} + +.panel { + width: 100%; + height: 100%; + display: flex; + flex-direction: column; + box-sizing: border-box; + overflow: hidden; + position: relative; +} + + +.panel-header { + display: flex; + align-items: flex-start; + justify-content: space-between; + gap: 12px; + min-width: 0; /* required so children can actually shrink/ellipsize instead of forcing overflow */ +} + +.panel-header-text { + min-width: 0; + flex: 1 1 auto; +} + +.panel-title { + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} + +.mono { + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} + +.specs { + flex-shrink: 0; +} + +.panel-actions { + position: absolute; + right: 16px; + bottom: 16px; + margin: 0; /* drop margin-top: auto, no longer needed */ + padding: 0; /* drop padding-top: 16px, spacing now handled by right/bottom offsets */ +} + +.connection-section { + position: absolute; /* was: fixed — relative to .dsp-content now */ + inset: 0; /* replaces top:0; right:0; bottom:0; left:0 */ + + display: flex; + justify-content: center; + align-items: center; +} \ No newline at end of file diff --git a/src/components/dsp408/ConnectionSection/ConnectionSection.tsx b/src/components/dsp408/ConnectionSection/ConnectionSection.tsx new file mode 100644 index 0000000..2816d26 --- /dev/null +++ b/src/components/dsp408/ConnectionSection/ConnectionSection.tsx @@ -0,0 +1,97 @@ +// ConnectionPanel.tsx +import { DSP } from '../../../types/types'; +import Button from '../../Button/Button'; +import AutoScale from '../../AutoScale/AutoScale'; +import './ConnectionSection.css'; + +const DESIGN_WIDTH = 340; +const DESIGN_HEIGHT = 280; + +const BTN_W = 100; +const BTN_H = 40; + +function ConnectionPanel({ + dsp, + onConnect, + onDisconnect, +}: { + dsp: DSP; + onConnect: () => void; + onDisconnect: () => void; +}) { + const statusLabel = + dsp.status === 'connected' + ? 'Connected' + : dsp.status === 'connecting' + ? 'Connecting…' + : 'Disconnected'; + + return ( +
+
+ +
+
+
+

+ {dsp.name} +

+
{dsp.type}
+
+ +
+ + {statusLabel} +
+
+ +
+
+
IP address
+
+ {dsp.ip} +
+
+ +
+
Port
+
{dsp.port}
+
+ +
+
Device ID
+
+ {dsp.deviceId || '—'} +
+
+
+ +
+ {dsp.status === 'connected' ? ( + + ) : ( + + )} +
+
+
+
+
+ ); +} + +export default ConnectionPanel; \ No newline at end of file diff --git a/src/components/dsp408/GainSection/GainSection.css b/src/components/dsp408/GainSection/GainSection.css index 7370cd4..178314e 100644 --- a/src/components/dsp408/GainSection/GainSection.css +++ b/src/components/dsp408/GainSection/GainSection.css @@ -1,10 +1,10 @@ :root { - --gain-section-height: 50vh; /* your fixed % of screen height */ + --gain-section-height: 40vh; } .gain-section { - position: fixed; - left: var(--sidebar-width-collapsed); + position: absolute; /* was: fixed — now relative to .dsp-content, which is the fixed+inset parent */ + left: 0; /* was: var(--sidebar-width-collapsed) — .dsp-content already excludes the sidebar */ right: 0; bottom: 0; @@ -18,17 +18,13 @@ box-sizing: border-box; padding: 0 var(--space-4); - background: var(--bg-void); - - transition: left var(--dur-base) var(--ease-standard); + background: var(--bg-panel); z-index: 20; + + border-top: 1px solid var(--border-hairline); } -/* keep it clear of the sidebar when expanded, without lifting React state */ -.app-root:has(.sidebar-rail--expanded) .gain-section { - left: var(--sidebar-width-expanded); -} .gain-panels { display: flex; flex-direction: row; @@ -72,6 +68,7 @@ border-radius: var(--radius-md); box-sizing: border-box; padding: 8px; + background: var(--bg-void); } .gain-panel__title { diff --git a/src/pages/DspPage/DspPage.css b/src/pages/DspPage/DspPage.css new file mode 100644 index 0000000..c698ea5 --- /dev/null +++ b/src/pages/DspPage/DspPage.css @@ -0,0 +1,13 @@ +.dsp-content { + position: fixed; + left: var(--sidebar-width-collapsed); + right: 0; + top: 0; + bottom: 0; + transition: left var(--dur-base) var(--ease-standard); + top: var(--header-height, 0); +} + +.app-root:has(.sidebar-rail--expanded) .dsp-content { + left: var(--sidebar-width-expanded); +} diff --git a/src/pages/DspPage.tsx b/src/pages/DspPage/DspPage.tsx similarity index 71% rename from src/pages/DspPage.tsx rename to src/pages/DspPage/DspPage.tsx index 71a3f7c..70967b0 100644 --- a/src/pages/DspPage.tsx +++ b/src/pages/DspPage/DspPage.tsx @@ -1,10 +1,11 @@ import { useState } from 'react'; -import { DSP } from '../types/types'; -import Sidebar from '../components/Sidebar/Sidebar'; -import { InfoIcon, SlidersIcon } from '../assets/icons/AudioIcons'; -import ConnectionPanel from '../components/dsp408/ConnectionPanel'; -import GainSection from '../components/dsp408/GainSection/GainSection'; -import { NotificationType } from '../types/types'; +import { DSP } from '../../types/types'; +import Sidebar from '../../components/Sidebar/Sidebar'; +import { InfoIcon, SlidersIcon } from '../../assets/icons/AudioIcons'; +import ConnectionPanel from '../../components/dsp408/ConnectionSection/ConnectionSection'; +import GainSection from '../../components/dsp408/GainSection/GainSection'; +import { NotificationType } from '../../types/types'; +import './DspPage.css' function DSPPage({ dsp, @@ -47,7 +48,7 @@ function DSPPage({ }; return ( -
+