fix(playground): improve OSC UI discoverability and mobile layout

- OSC pill: add status dot indicator (gray=off, green=connected,
  pulsing yellow=connecting), use flexbox for reliable alignment
- OSC pill: add hover state for better affordance
- Synth panel: add separator line above OSC row so it doesn't
  blend into the arpeggiator controls
- Bottom sheet: increase expanded height from 55vh to 60vh so
  OSC row isn't cut off on mobile
- Help modal: update step 3 to mention the OSC pill in the
  bottom bar as the primary connection method
This commit is contained in:
w1n5t0n 2026-03-25 12:01:12 +02:00
parent b4d3311b32
commit e8b4067c91
2 changed files with 58 additions and 11 deletions

View file

@ -190,7 +190,7 @@
<div class="synth-row" id="midi-status-row" style="display:none">
<span class="synth-status" id="midi-status"></span>
</div>
<div class="synth-row" id="osc-row">
<div class="synth-row osc-row-panel" id="osc-row">
<label>OSC Output</label>
<button class="action-btn" id="osc-toggle">Connect</button>
<span class="synth-status" id="osc-status">Off</span>
@ -325,7 +325,7 @@
<pre class="help-code" id="osc-run-instructions">./nisps-osc-bridge</pre>
<p><strong>3. Connect</strong></p>
<p>In the synth panel below, click <strong>Connect</strong> next to "OSC Output". The status will show the target address once connected.</p>
<p>Click the <strong>OSC</strong> button in the bottom bar (visible in all modes). The dot turns green when connected. You can also find a Connect button in the synth panel when expanded.</p>
</div>
<p style="margin-top:10px"><strong>Configuration</strong></p>

View file

@ -676,28 +676,68 @@ html, body {
}
.osc-pill {
padding: 4px 12px;
padding: 4px 10px;
border-radius: 6px;
border: 1px solid rgba(255, 255, 255, 0.08);
background: rgba(255, 255, 255, 0.04);
border: 1px solid rgba(255, 255, 255, 0.12);
background: rgba(255, 255, 255, 0.05);
color: var(--text-dim);
font-size: 12px;
font-size: 11px;
font-weight: 500;
letter-spacing: 0.5px;
cursor: pointer;
transition: all 0.15s;
display: inline-flex;
align-items: center;
gap: 5px;
}
/* Dot indicator before text */
.osc-pill::before {
content: '';
flex-shrink: 0;
width: 6px;
height: 6px;
border-radius: 50%;
background: rgba(255, 255, 255, 0.2);
transition: all 0.15s;
}
.osc-pill:hover {
border-color: rgba(255, 255, 255, 0.25);
color: var(--text);
}
.osc-pill:hover::before {
background: rgba(255, 255, 255, 0.4);
}
.osc-pill.connected {
background: rgba(0, 200, 120, 0.15);
border-color: rgba(0, 200, 120, 0.4);
background: rgba(0, 200, 120, 0.12);
border-color: rgba(0, 200, 120, 0.35);
color: #00c878;
}
.osc-pill.connected::before {
background: #00c878;
box-shadow: 0 0 4px rgba(0, 200, 120, 0.5);
}
.osc-pill.connecting {
background: rgba(255, 200, 0, 0.1);
border-color: rgba(255, 200, 0, 0.3);
background: rgba(255, 200, 0, 0.08);
border-color: rgba(255, 200, 0, 0.25);
color: #ffc800;
}
.osc-pill.connecting::before {
background: #ffc800;
animation: osc-pulse 1s ease-in-out infinite;
}
@keyframes osc-pulse {
0%, 100% { opacity: 1; }
50% { opacity: 0.3; }
}
.chevron-btn {
width: 32px;
height: 32px;
@ -741,7 +781,7 @@ html, body {
}
.bottom-sheet.expanded {
height: 55vh;
height: 60vh;
overflow-y: auto;
-webkit-overflow-scrolling: touch;
}
@ -920,6 +960,13 @@ html, body {
font-size: 12px;
}
/* OSC row in synth panel — visual separator from arp controls above */
.osc-row-panel {
margin-top: 6px;
padding-top: 10px;
border-top: 1px solid rgba(255, 255, 255, 0.06);
}
.synth-status {
font-size: 11px;
color: var(--text-dim);