fix: btn-icon touch targets to 44px WCGA minimum

- CSS classes: index.css (28→44px base, 24→44px mobile), App.jsx (36→44px base, 24→44px narrow)
- 19 inline btn-icon buttons in App.jsx: param view toggle, CapturesScreen/Presets close, sidebar toggle, undo/redo, status bar nav (captures/presets/tuner/fullscreen/menu), overlay closes, global bypass toggle, block bypass toggle, Scan/ON buttons, add block close
- Footswitch mode SM/PR buttons: height 20→44px, minWidth 34→44px
- FocusView.jsx: param −/+ buttons 34→44px, close button 34→44px
- GlobalSettings.jsx: param −/+ buttons 26→44px, close button 34→44px
- border-radius bumped from 7→8px (base), 5→8px (index.css) for proportion
This commit is contained in:
2026-06-14 18:37:58 -04:00
parent a5a01fda02
commit 3dcf31f600
4 changed files with 38 additions and 36 deletions
+26 -26
View File
@@ -150,7 +150,7 @@ const css = `
.btn-primary:active { filter: brightness(.85); transform: scale(.97); } .btn-primary:active { filter: brightness(.85); transform: scale(.97); }
.btn-ghost { background: var(--surface); color: var(--text-primary); border: 1px solid var(--border); } .btn-ghost { background: var(--surface); color: var(--text-primary); border: 1px solid var(--border); }
.btn-ghost:active { background: var(--border); } .btn-ghost:active { background: var(--border); }
.btn-icon { width: 36px; height: 36px; border-radius: 7px; display: flex; align-items: center; .btn-icon { width: 44px; height: 44px; border-radius: 8px; display: flex; align-items: center;
justify-content: center; background: var(--surface); border: 1px solid var(--border); cursor: pointer; justify-content: center; background: var(--surface); border: 1px solid var(--border); cursor: pointer;
font-size: 15px; transition: all .12s; flex-shrink: 0; } font-size: 15px; transition: all .12s; flex-shrink: 0; }
.btn-icon:active { transform: scale(.93); } .btn-icon:active { transform: scale(.93); }
@@ -222,7 +222,7 @@ const css = `
.screen-title { font-size: 11px; } .screen-title { font-size: 11px; }
.screen-body { padding: 8px 10px; gap: 8px; } .screen-body { padding: 8px 10px; gap: 8px; }
.knob-wrap { transform: scale(.9); } .knob-wrap { transform: scale(.9); }
.btn-icon { width: 24px; height: 24px; font-size: 10px; } .btn-icon { width: 44px; height: 44px; font-size: 12px; }
} }
/* ── Responsive: landscape short ── */ /* ── Responsive: landscape short ── */
@@ -377,7 +377,7 @@ function ParameterPanel({ block,params,onParamChange,onParamChangeEnd,viewMode,o
<div style={{display:'flex',gap:4,alignItems:'center'}}> <div style={{display:'flex',gap:4,alignItems:'center'}}>
{onFocus&&<button className="btn" style={{padding:'4px 8px',fontSize:9,fontWeight:600,background:`${T.amber}22`,border:`1px solid ${T.amber}44`,color:T.amber,borderRadius:5,letterSpacing:'.04em',cursor:'pointer'}} {onFocus&&<button className="btn" style={{padding:'4px 8px',fontSize:9,fontWeight:600,background:`${T.amber}22`,border:`1px solid ${T.amber}44`,color:T.amber,borderRadius:5,letterSpacing:'.04em',cursor:'pointer'}}
onClick={onFocus}>🔍 Focus</button>} onClick={onFocus}>🔍 Focus</button>}
<button className="btn-icon" style={{width:26,height:26,fontSize:11,flexShrink:0}} <button className="btn-icon" style={{width:44,height:44,fontSize:14,flexShrink:0}}
onClick={onToggleView}>{viewMode==='slider'?'◉':'▦'}</button> onClick={onToggleView}>{viewMode==='slider'?'◉':'▦'}</button>
</div> </div>
</div> </div>
@@ -422,7 +422,7 @@ function CapturesScreen({onClose}){
const doSearch=async()=>{if(!query.trim())return;setLoading(true);try{const data=tab==="models"?await API.searchModels(query):await API.searchIrs(query);setResults(data.results||[]);}catch{setResults([]);}setLoading(false);}; const doSearch=async()=>{if(!query.trim())return;setLoading(true);try{const data=tab==="models"?await API.searchModels(query):await API.searchIrs(query);setResults(data.results||[]);}catch{setResults([]);}setLoading(false);};
const install=async(item)=>{try{if(tab==="models"){await API.installModel(item.download_url,item.name);}else{await API.installIr(item.download_url,item.name);}API.listModels().then(d=>setModels(d.models||[])).catch(()=>{});}catch(e){alert("Install failed: "+e.message);}}; const install=async(item)=>{try{if(tab==="models"){await API.installModel(item.download_url,item.name);}else{await API.installIr(item.download_url,item.name);}API.listModels().then(d=>setModels(d.models||[])).catch(()=>{});}catch(e){alert("Install failed: "+e.message);}};
return(<div style={{display:"flex",flexDirection:"column",height:"100%",background:T.bg}}> return(<div style={{display:"flex",flexDirection:"column",height:"100%",background:T.bg}}>
<div className="screen-header"><div className="screen-title">Downloads</div><button className="btn-icon" style={{width:36,height:36,fontSize:13}}onClick={onClose}></button></div> <div className="screen-header"><div className="screen-title">Downloads</div><button className="btn-icon" style={{width:44,height:44,fontSize:16}}onClick={onClose}></button></div>
<div style={{padding:"6px 12px",borderBottom:`1px solid ${T.border}`}}><div className="toggle"> <div style={{padding:"6px 12px",borderBottom:`1px solid ${T.border}`}}><div className="toggle">
<button className={`toggle-btn ${tab==="models"?"active":""}`}onClick={()=>setTab("models")}>NAM Models</button> <button className={`toggle-btn ${tab==="models"?"active":""}`}onClick={()=>setTab("models")}>NAM Models</button>
<button className={`toggle-btn ${tab==="irs"?"active":""}`}onClick={()=>setTab("irs")}>IR Cabs</button></div></div> <button className={`toggle-btn ${tab==="irs"?"active":""}`}onClick={()=>setTab("irs")}>IR Cabs</button></div></div>
@@ -831,7 +831,7 @@ export default function App(){
padding:isLandscapeShort?"2px 10px":"4px 12px",background:T.panel,borderBottom:`1px solid ${T.border}`,flexShrink:0,minHeight:isLandscapeShort?26:32}}> padding:isLandscapeShort?"2px 10px":"4px 12px",background:T.panel,borderBottom:`1px solid ${T.border}`,flexShrink:0,minHeight:isLandscapeShort?26:32}}>
<div style={{display:"flex",gap:8,alignItems:"center"}}> <div style={{display:"flex",gap:8,alignItems:"center"}}>
{/* Sidebar toggle (narrow only) */} {/* Sidebar toggle (narrow only) */}
{isNarrow&&<button className="btn-icon" style={{width:24,height:24,fontSize:13,position:'relative',marginRight:-2}} {isNarrow&&<button className="btn-icon" style={{width:44,height:44,fontSize:16,position:'relative',marginRight:-2}}
onClick={()=>setSidebarOpen(s=>!s)} title="Presets"> onClick={()=>setSidebarOpen(s=>!s)} title="Presets">
<span style={{fontSize:12,lineHeight:1}}></span> <span style={{fontSize:12,lineHeight:1}}></span>
</button>} </button>}
@@ -839,11 +839,11 @@ export default function App(){
background:state.connected?T.green:T.red,boxShadow:`0 0 6px ${state.connected?T.green:T.red}`}}/> background:state.connected?T.green:T.red,boxShadow:`0 0 6px ${state.connected?T.green:T.red}`}}/>
{!isNarrow&&<span className="mono" style={{fontSize:9,color:state.connected?T.green:T.red}}>{state.connected?"CONNECTED":"OFFLINE"}</span>} {!isNarrow&&<span className="mono" style={{fontSize:9,color:state.connected?T.green:T.red}}>{state.connected?"CONNECTED":"OFFLINE"}</span>}
{/* Undo/Redo */} {/* Undo/Redo */}
<button className="btn-icon" style={{width:20,height:20,fontSize:11,opacity:undoStack.length>0?1:0.3}} <button className="btn-icon" style={{width:44,height:44,fontSize:14,opacity:undoStack.length>0?1:0.3}}
onClick={handleUndo} disabled={undoStack.length===0} title="Undo (Ctrl+Z)"> onClick={handleUndo} disabled={undoStack.length===0} title="Undo (Ctrl+Z)">
</button> </button>
<button className="btn-icon" style={{width:20,height:20,fontSize:11,opacity:redoStack.length>0?1:0.3}} <button className="btn-icon" style={{width:44,height:44,fontSize:14,opacity:redoStack.length>0?1:0.3}}
onClick={handleRedo} disabled={redoStack.length===0} title="Redo (Ctrl+Shift+Z)"> onClick={handleRedo} disabled={redoStack.length===0} title="Redo (Ctrl+Shift+Z)">
</button> </button>
@@ -859,34 +859,34 @@ export default function App(){
<span className="mono" style={{fontSize:9,color:T.textSec}}>CPU <span style={{color:T.amber,fontWeight:700}}>{state.cpu_percent!=null?`${state.cpu_percent}%`:"—"}</span></span> <span className="mono" style={{fontSize:9,color:T.textSec}}>CPU <span style={{color:T.amber,fontWeight:700}}>{state.cpu_percent!=null?`${state.cpu_percent}%`:"—"}</span></span>
</div>} </div>}
<div style={{width:1,height:12,background:T.border}}/> <div style={{width:1,height:12,background:T.border}}/>
<button className="btn-icon" style={{width:24,height:24,position:'relative'}}onClick={()=>setView("captures")}title="Downloads"> <button className="btn-icon" style={{width:44,height:44,position:"relative"}}onClick={()=>setView("captures")} title="Downloads">
<img src={`${import.meta.env.BASE_URL}img/ic_bank.svg`} alt="captures" style={{width:14,height:14}}/> <img src={`${import.meta.env.BASE_URL}img/ic_bank.svg`} alt="captures" style={{width:14,height:14}}/>
</button> </button>
<button className="btn-icon" style={{width:24,height:24,position:'relative'}}onClick={()=>setView("presets")}title="Presets"> <button className="btn-icon" style={{width:44,height:44,position:"relative"}}onClick={()=>setView("presets")}title="Presets">
<img src={`${import.meta.env.BASE_URL}img/ic_presets.svg`} alt="presets" style={{width:14,height:14}}/> <img src={`${import.meta.env.BASE_URL}img/ic_presets.svg`} alt="presets" style={{width:14,height:14}}/>
</button> </button>
<div style={{display:"flex",gap:2,alignItems:"center",background:T.surface,borderRadius:4,border:`1px solid ${T.border}`,padding:2,height:24}}> <div style={{display:"flex",gap:2,alignItems:"center",background:T.surface,borderRadius:4,border:`1px solid ${T.border}`,padding:2,height:24}}>
{["stomp","preset"].map(m=>(<button key={m} onClick={()=>setFootswitchMode(m)} style={{ {["stomp","preset"].map(m=>(<button key={m} onClick={()=>setFootswitchMode(m)} style={{
padding:"1px 5px",borderRadius:3,border:"none",height:20, padding:"1px 5px",borderRadius:3,border:"none",height:44,
fontSize:8,fontWeight:700,letterSpacing:".04em",textTransform:"uppercase", fontSize:8,fontWeight:700,letterSpacing:".04em",textTransform:"uppercase",
background:footswitchMode===m?T.amber:"transparent", background:footswitchMode===m?T.amber:"transparent",
color:footswitchMode===m?"#000":T.textDim, color:footswitchMode===m?"#000":T.textDim,
cursor:"pointer",lineHeight:1.5,minWidth:34,display:"flex",alignItems:"center",justifyContent:"center", cursor:"pointer",lineHeight:1.5,minWidth:44,display:"flex",alignItems:"center",justifyContent:"center",
}}>{m==="stomp"?"SM":"PR"}</button>))} }}>{m==="stomp"?"SM":"PR"}</button>))}
</div> </div>
<button className="btn-icon" style={{width:24,height:24,position:'relative', <button className="btn-icon" style={{width:44,height:44,position:"relative",
background:state.tuner_enabled?'rgba(128,208,160,.15)':T.surface, background:state.tuner_enabled?"rgba(128,208,160,.15)":T.surface,
borderColor:state.tuner_enabled?T.green:T.border}} borderColor:state.tuner_enabled?T.green:T.border}}
onClick={handleTunerToggle} title={state.tuner_enabled?"Exit Tuner":"Tuner"}> onClick={handleTunerToggle} title={state.tuner_enabled?"Exit Tuner":"Tuner"}>
<img src={`${import.meta.env.BASE_URL}img/fx_analyzer.svg`} alt="tuner" style={{width:14,height:14,filter:state.tuner_enabled?'brightness(0) saturate(100%) invert(0.9) sepia(0.4) hue-rotate(80deg)':'none'}}/> <img src={`${import.meta.env.BASE_URL}img/fx_analyzer.svg`} alt="tuner" style={{width:14,height:14,filter:state.tuner_enabled?'brightness(0) saturate(100%) invert(0.9) sepia(0.4) hue-rotate(80deg)':'none'}}/>
</button> </button>
<button className="btn-icon" style={{width:24,height:24,position:'relative',background:'rgba(232,160,48,.12)',borderColor:T.amber}}onClick={()=>{if(!document.fullscreenElement){document.documentElement.requestFullscreen()}else{document.exitFullscreen()}}}title="Fullscreen"> <button className="btn-icon" style={{width:44,height:44,position:'relative',background:'rgba(232,160,48,.12)',borderColor:T.amber}}onClick={()=>{if(!document.fullscreenElement){document.documentElement.requestFullscreen()}else{document.exitFullscreen()}}}title="Fullscreen">
<svg viewBox="0 0 24 24" width="14" height="14" fill="#E8A030"> <svg viewBox="0 0 24 24" width="14" height="14" fill="#E8A030">
<path d="M7 14H5v5h5v-2H7v-3zm-2-4h2V7h3V5H5v5zm12 7h-3v2h5v-5h-2v3zM14 5v2h3v3h2V5h-5z"/> <path d="M7 14H5v5h5v-2H7v-3zm-2-4h2V7h3V5H5v5zm12 7h-3v2h5v-5h-2v3zM14 5v2h3v3h2V5h-5z"/>
</svg> </svg>
</button> </button>
<div style={{width:1,height:16,background:T.border}}/> <div style={{width:1,height:16,background:T.border}}/>
<button className="btn-icon" style={{width:24,height:24,position:'relative'}} <button className="btn-icon" style={{width:44,height:44,position:"relative"}}
onClick={()=>setMenuOpen(true)} title="Main Menu"> onClick={()=>setMenuOpen(true)} title="Main Menu">
<span style={{fontSize:14,color:T.amber,lineHeight:1}}></span> <span style={{fontSize:14,color:T.amber,lineHeight:1}}></span>
</button> </button>
@@ -1027,7 +1027,7 @@ export default function App(){
{view==="captures"&&<CapturesScreen onClose={()=>setView("main")}/>} {view==="captures"&&<CapturesScreen onClose={()=>setView("main")}/>}
{view==="presets"&&( {view==="presets"&&(
<div style={{display:"flex",flexDirection:"column",height:"100%",background:T.bg}}> <div style={{display:"flex",flexDirection:"column",height:"100%",background:T.bg}}>
<div className="screen-header"><div className="screen-title">Presets</div><button className="btn-icon"style={{width:36,height:36,fontSize:13}}onClick={()=>setView("main")}></button></div> <div className="screen-header"><div className="screen-title">Presets</div><button className="btn-icon"style={{width:44,height:44,fontSize:16}}onClick={()=>setView("main")}></button></div>
<div className="screen-body"> <div className="screen-body">
{presets.map((p,i)=>( {presets.map((p,i)=>(
<div key={i} className={`preset-row ${p.num===currentPreset?"active":""}`} <div key={i} className={`preset-row ${p.num===currentPreset?"active":""}`}
@@ -1102,7 +1102,7 @@ export default function App(){
<div className="card" style={{width:320,maxWidth:"85vw",padding:20}}> <div className="card" style={{width:320,maxWidth:"85vw",padding:20}}>
<div style={{display:"flex",justifyContent:"space-between",alignItems:"center",marginBottom:16}}> <div style={{display:"flex",justifyContent:"space-between",alignItems:"center",marginBottom:16}}>
<div style={{fontSize:14,fontWeight:600,color:T.textPrimary}}>💾 Save Preset</div> <div style={{fontSize:14,fontWeight:600,color:T.textPrimary}}>💾 Save Preset</div>
<button className="btn-icon" style={{width:26,height:26,fontSize:12}}onClick={()=>setOverlayView(null)}></button> <button className="btn-icon" style={{width:44,height:44,fontSize:14}}onClick={()=>setOverlayView(null)}></button>
</div> </div>
<div style={{display:"flex",flexDirection:"column",gap:12}}> <div style={{display:"flex",flexDirection:"column",gap:12}}>
<div> <div>
@@ -1133,12 +1133,12 @@ export default function App(){
<div className="card" style={{width:340,maxWidth:"85vw",padding:20}}> <div className="card" style={{width:340,maxWidth:"85vw",padding:20}}>
<div style={{display:"flex",justifyContent:"space-between",alignItems:"center",marginBottom:16}}> <div style={{display:"flex",justifyContent:"space-between",alignItems:"center",marginBottom:16}}>
<div style={{fontSize:14,fontWeight:600,color:T.textPrimary}}>🔌 Bypass / Control</div> <div style={{fontSize:14,fontWeight:600,color:T.textPrimary}}>🔌 Bypass / Control</div>
<button className="btn-icon" style={{width:26,height:26,fontSize:12}}onClick={()=>setOverlayView(null)}></button> <button className="btn-icon" style={{width:44,height:44,fontSize:14}}onClick={()=>setOverlayView(null)}></button>
</div> </div>
<div style={{display:"flex",flexDirection:"column",gap:14}}> <div style={{display:"flex",flexDirection:"column",gap:14}}>
<div style={{display:"flex",justifyContent:"space-between",alignItems:"center"}}> <div style={{display:"flex",justifyContent:"space-between",alignItems:"center"}}>
<span style={{fontSize:12,color:T.textPrimary}}>🚫 Global Bypass</span> <span style={{fontSize:12,color:T.textPrimary}}>🚫 Global Bypass</span>
<button className="btn-icon" style={{width:40,height:26,fontSize:10,background:globalBypass?`${T.red}22`:T.surface,borderColor:globalBypass?T.red:T.border}} <button className="btn-icon" style={{width:44,height:44,fontSize:10,background:globalBypass?`${T.red}22`:T.surface,borderColor:globalBypass?T.red:T.border}}
onClick={()=>{setGlobalBypass(p=>!p);API.bypassToggle().catch(()=>{});}}> onClick={()=>{setGlobalBypass(p=>!p);API.bypassToggle().catch(()=>{});}}>
{globalBypass?"ON":"OFF"} {globalBypass?"ON":"OFF"}
</button> </button>
@@ -1149,7 +1149,7 @@ export default function App(){
{blocks.map(b=>( {blocks.map(b=>(
<div key={b.id} style={{display:"flex",justifyContent:"space-between",alignItems:"center",padding:"4px 0"}}> <div key={b.id} style={{display:"flex",justifyContent:"space-between",alignItems:"center",padding:"4px 0"}}>
<span style={{fontSize:11,color:T.textPrimary}}>{b.name||b.type}</span> <span style={{fontSize:11,color:T.textPrimary}}>{b.name||b.type}</span>
<button className="btn-icon" style={{width:36,height:22,fontSize:9,background:b.bypassed?`${T.red}22`:T.surface,borderColor:b.bypassed?T.red:T.border}} <button className="btn-icon" style={{width:44,height:44,fontSize:11,background:b.bypassed?`${T.red}22`:T.surface,borderColor:b.bypassed?T.red:T.border}}
onClick={()=>handleToggleBlock(b.id)}> onClick={()=>handleToggleBlock(b.id)}>
{b.bypassed?"BYP":"ACT"} {b.bypassed?"BYP":"ACT"}
</button> </button>
@@ -1180,12 +1180,12 @@ export default function App(){
<div className="card" style={{width:340,maxWidth:"85vw",padding:20}}> <div className="card" style={{width:340,maxWidth:"85vw",padding:20}}>
<div style={{display:"flex",justifyContent:"space-between",alignItems:"center",marginBottom:16}}> <div style={{display:"flex",justifyContent:"space-between",alignItems:"center",marginBottom:16}}>
<div style={{fontSize:14,fontWeight:600,color:T.textPrimary}}>📶 Wireless</div> <div style={{fontSize:14,fontWeight:600,color:T.textPrimary}}>📶 Wireless</div>
<button className="btn-icon" style={{width:26,height:26,fontSize:12}}onClick={()=>setOverlayView(null)}></button> <button className="btn-icon" style={{width:44,height:44,fontSize:14}}onClick={()=>setOverlayView(null)}></button>
</div> </div>
<div style={{display:"flex",flexDirection:"column",gap:14}}> <div style={{display:"flex",flexDirection:"column",gap:14}}>
<div style={{display:"flex",justifyContent:"space-between",alignItems:"center"}}> <div style={{display:"flex",justifyContent:"space-between",alignItems:"center"}}>
<span style={{fontSize:12,color:T.textPrimary}}>📶 WiFi</span> <span style={{fontSize:12,color:T.textPrimary}}>📶 WiFi</span>
<button className="btn-icon" style={{width:40,height:26,fontSize:10}}>Scan</button> <button className="btn-icon" style={{width:44,height:44,fontSize:11}}>Scan</button>
</div> </div>
<div className="card-sm" style={{textAlign:"center",padding:16}}> <div className="card-sm" style={{textAlign:"center",padding:16}}>
<span style={{fontSize:11,color:T.textSec}}>Use pedal as access point or connect to existing network via the settings panel.</span> <span style={{fontSize:11,color:T.textSec}}>Use pedal as access point or connect to existing network via the settings panel.</span>
@@ -1193,7 +1193,7 @@ export default function App(){
<div style={{height:1,background:T.border}}/> <div style={{height:1,background:T.border}}/>
<div style={{display:"flex",justifyContent:"space-between",alignItems:"center"}}> <div style={{display:"flex",justifyContent:"space-between",alignItems:"center"}}>
<span style={{fontSize:12,color:T.textPrimary}}>🔵 Bluetooth</span> <span style={{fontSize:12,color:T.textPrimary}}>🔵 Bluetooth</span>
<button className="btn-icon" style={{width:40,height:26,fontSize:10,background:`${T.blue}22`,borderColor:T.blue,color:T.blue}}>ON</button> <button className="btn-icon" style={{width:44,height:44,fontSize:11,background:`${T.blue}22`,borderColor:T.blue,color:T.blue}}>ON</button>
</div> </div>
<div style={{fontSize:10,color:T.textSec}}>Bluetooth MIDI is enabled. Pair with your mobile device or MIDI controller.</div> <div style={{fontSize:10,color:T.textSec}}>Bluetooth MIDI is enabled. Pair with your mobile device or MIDI controller.</div>
</div> </div>
@@ -1208,7 +1208,7 @@ export default function App(){
<div className="card" style={{width:320,maxWidth:"85vw",padding:20,maxHeight:"80vh",overflowY:"auto"}}> <div className="card" style={{width:320,maxWidth:"85vw",padding:20,maxHeight:"80vh",overflowY:"auto"}}>
<div style={{display:"flex",justifyContent:"space-between",alignItems:"center",marginBottom:12}}> <div style={{display:"flex",justifyContent:"space-between",alignItems:"center",marginBottom:12}}>
<div style={{fontSize:13,fontWeight:600,color:T.textPrimary}}>+ Add Block</div> <div style={{fontSize:13,fontWeight:600,color:T.textPrimary}}>+ Add Block</div>
<button className="btn-icon" style={{width:24,height:24,fontSize:11}}onClick={()=>setAddBlockType(null)}></button> <button className="btn-icon" style={{width:44,height:44,fontSize:14}}onClick={()=>setAddBlockType(null)}></button>
</div> </div>
<div style={{display:"grid",gridTemplateColumns:"1fr 1fr",gap:6}}> <div style={{display:"grid",gridTemplateColumns:"1fr 1fr",gap:6}}>
{Object.entries(BLOCK_DISPLAY_NAMES).filter(([k])=>!["loop","split","merge"].includes(k)).map(([type,name])=>( {Object.entries(BLOCK_DISPLAY_NAMES).filter(([k])=>!["loop","split","merge"].includes(k)).map(([type,name])=>(
+3 -3
View File
@@ -164,7 +164,7 @@ function FocusSlider({ label, value = 50, onChange, onChangeEnd, min = 0, max =
<span style={{ fontSize: 11, fontWeight: 500, textTransform: 'uppercase', letterSpacing: '.06em', color }}>{label}</span> <span style={{ fontSize: 11, fontWeight: 500, textTransform: 'uppercase', letterSpacing: '.06em', color }}>{label}</span>
<div style={{ display: 'flex', gap: 8, alignItems: 'center' }}> <div style={{ display: 'flex', gap: 8, alignItems: 'center' }}>
<button style={{ <button style={{
width: 34, height: 34, borderRadius: '50%', border: `1px solid ${T.border}`, width: 44, height: 44, borderRadius: '50%', border: `1px solid ${T.border}`,
background: T.panel, color: T.textPrimary, fontSize: 16, fontWeight: 700, background: T.panel, color: T.textPrimary, fontSize: 16, fontWeight: 700,
display: 'flex', alignItems: 'center', justifyContent: 'center', cursor: 'pointer', display: 'flex', alignItems: 'center', justifyContent: 'center', cursor: 'pointer',
lineHeight: 1, lineHeight: 1,
@@ -174,7 +174,7 @@ function FocusSlider({ label, value = 50, onChange, onChangeEnd, min = 0, max =
minWidth: 40, textAlign: 'center', minWidth: 40, textAlign: 'center',
}}>{touchVal ?? value}</span> }}>{touchVal ?? value}</span>
<button style={{ <button style={{
width: 34, height: 34, borderRadius: '50%', border: `1px solid ${T.border}`, width: 44, height: 44, borderRadius: '50%', border: `1px solid ${T.border}`,
background: T.panel, color: T.textPrimary, fontSize: 16, fontWeight: 700, background: T.panel, color: T.textPrimary, fontSize: 16, fontWeight: 700,
display: 'flex', alignItems: 'center', justifyContent: 'center', cursor: 'pointer', display: 'flex', alignItems: 'center', justifyContent: 'center', cursor: 'pointer',
lineHeight: 1, lineHeight: 1,
@@ -336,7 +336,7 @@ export default function FocusView({
<div style={{ display: 'flex', alignItems: 'center', gap: 10, minWidth: 0 }}> <div style={{ display: 'flex', alignItems: 'center', gap: 10, minWidth: 0 }}>
<button onClick={onClose} <button onClick={onClose}
style={{ style={{
width: 34, height: 34, borderRadius: 8, width: 44, height: 44, borderRadius: 8,
display: 'flex', alignItems: 'center', justifyContent: 'center', display: 'flex', alignItems: 'center', justifyContent: 'center',
background: T.surface, border: `1px solid ${T.border}`, background: T.surface, border: `1px solid ${T.border}`,
color: T.textPrimary, fontSize: 16, cursor: 'pointer', color: T.textPrimary, fontSize: 16, cursor: 'pointer',
+3 -3
View File
@@ -169,7 +169,7 @@ function SettingsSlider({ label, value, min, max, unit, onChange }) {
<span style={{ fontSize: 11, fontWeight: 500, color: T.textSec }}>{label}</span> <span style={{ fontSize: 11, fontWeight: 500, color: T.textSec }}>{label}</span>
<div style={{ display: "flex", gap: 6, alignItems: "center" }}> <div style={{ display: "flex", gap: 6, alignItems: "center" }}>
<button style={{ <button style={{
width: 26, height: 26, borderRadius: "50%", border: `1px solid ${T.border}`, width: 44, height: 44, borderRadius: "50%", border: `1px solid ${T.border}`,
background: T.panel, color: T.textPrimary, fontSize: 14, fontWeight: 700, background: T.panel, color: T.textPrimary, fontSize: 14, fontWeight: 700,
display: "flex", alignItems: "center", justifyContent: "center", cursor: "pointer", lineHeight: 1, display: "flex", alignItems: "center", justifyContent: "center", cursor: "pointer", lineHeight: 1,
}} onMouseDown={quick(-1)} onTouchStart={quick(-1)}></button> }} onMouseDown={quick(-1)} onTouchStart={quick(-1)}></button>
@@ -178,7 +178,7 @@ function SettingsSlider({ label, value, min, max, unit, onChange }) {
minWidth: 36, textAlign: "center", minWidth: 36, textAlign: "center",
}}>{value}{unit}</span> }}>{value}{unit}</span>
<button style={{ <button style={{
width: 26, height: 26, borderRadius: "50%", border: `1px solid ${T.border}`, width: 44, height: 44, borderRadius: "50%", border: `1px solid ${T.border}`,
background: T.panel, color: T.textPrimary, fontSize: 14, fontWeight: 700, background: T.panel, color: T.textPrimary, fontSize: 14, fontWeight: 700,
display: "flex", alignItems: "center", justifyContent: "center", cursor: "pointer", lineHeight: 1, display: "flex", alignItems: "center", justifyContent: "center", cursor: "pointer", lineHeight: 1,
}} onMouseDown={quick(1)} onTouchStart={quick(1)}>+</button> }} onMouseDown={quick(1)} onTouchStart={quick(1)}>+</button>
@@ -392,7 +392,7 @@ export default function GlobalSettings({ onClose, onMasterVolume, onAudioProfile
<div style={{ position: "fixed", inset: 0, zIndex: 998, display: "flex", flexDirection: "column", background: T.bg, color: T.textPrimary, fontFamily: "'Space Grotesk', sans-serif" }}> <div style={{ position: "fixed", inset: 0, zIndex: 998, display: "flex", flexDirection: "column", background: T.bg, color: T.textPrimary, fontFamily: "'Space Grotesk', sans-serif" }}>
<div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", padding: "10px 14px", borderBottom: `1px solid ${T.border}`, background: T.panel, flexShrink: 0 }}> <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", padding: "10px 14px", borderBottom: `1px solid ${T.border}`, background: T.panel, flexShrink: 0 }}>
<div style={{ display: "flex", alignItems: "center", gap: 10 }}> <div style={{ display: "flex", alignItems: "center", gap: 10 }}>
<button onClick={onClose} style={{ width: 34, height: 34, borderRadius: 8, display: "flex", alignItems: "center", justifyContent: "center", background: T.surface, border: `1px solid ${T.border}`, color: T.textPrimary, fontSize: 16, cursor: "pointer" }}></button> <button onClick={onClose} style={{ width: 44, height: 44, borderRadius: 8, display: "flex", alignItems: "center", justifyContent: "center", background: T.surface, border: `1px solid ${T.border}`, color: T.textPrimary, fontSize: 16, cursor: "pointer" }}></button>
<div> <div>
<div style={{ fontSize: 15, fontWeight: 600 }}>Settings</div> <div style={{ fontSize: 15, fontWeight: 600 }}>Settings</div>
{!loaded && <span style={{ fontSize: 10, color: T.textDim }}>Loading</span>} {!loaded && <span style={{ fontSize: 10, color: T.textDim }}>Loading</span>}
+6 -4
View File
@@ -42,9 +42,11 @@ body { background: #0A0A0C; color: #F0EDE6; font-family: 'Space Grotesk', sans-s
.btn-ghost { background: transparent; border-color: transparent; } .btn-ghost { background: transparent; border-color: transparent; }
.btn-danger { border-color: #E06060; background: rgba(224,96,96,.15); color: #E06060; } .btn-danger { border-color: #E06060; background: rgba(224,96,96,.15); color: #E06060; }
.btn-icon { display: inline-flex; align-items: center; justify-content: center; .btn-icon { display: inline-flex; align-items: center; justify-content: center;
width: 28px; height: 28px; border-radius: 5px; border: 1px solid #2A2A32; width: 44px; height: 44px; border-radius: 8px; border: 1px solid #2A2A32;
background: #1C1C22; cursor: pointer; transition: all .12s; touch-action: manipulation; } background: #1C1C22; cursor: pointer; transition: all .12s; touch-action: manipulation; }
.btn-icon:active { transform: scale(.92); } .btn-icon:active { transform: scale(.92); }
.btn:focus-visible { outline: 2px solid #3AB87A; outline-offset: 2px; }
.btn-icon:focus-visible { outline: 2px solid #3AB87A; outline-offset: 2px; }
/* Slide panel (bottom drawer) */ /* Slide panel (bottom drawer) */
.slide-panel { position: fixed; inset: 0; background: rgba(0,0,0,.7); z-index: 100; .slide-panel { position: fixed; inset: 0; background: rgba(0,0,0,.7); z-index: 100;
@@ -186,9 +188,9 @@ body { background: #0A0A0C; color: #F0EDE6; font-family: 'Space Grotesk', sans-s
font-size: 11px; font-size: 11px;
} }
.btn-icon { .btn-icon {
width: 24px; width: 44px;
height: 24px; height: 44px;
font-size: 10px; font-size: 12px;
} }
.card { .card {
padding: 10px; padding: 10px;