NeonClary commited on
Commit
ebb59c0
·
1 Parent(s): caafa14

ui: group Settings into boxed sections, move persona to bottom

Browse files
Files changed (2) hide show
  1. frontend/src/App.css +26 -1
  2. frontend/src/App.jsx +49 -43
frontend/src/App.css CHANGED
@@ -186,8 +186,33 @@ html.aj-hide-pointer * {
186
  box-shadow: var(--lc-shadow);
187
  }
188
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
189
  .aj-options-hint {
190
- margin: 10px 0 0;
191
  font-size: 12px;
192
  color: var(--lc-muted);
193
  line-height: 1.45;
 
186
  box-shadow: var(--lc-shadow);
187
  }
188
 
189
+ .aj-options-section {
190
+ padding: 14px;
191
+ border-radius: 10px;
192
+ border: 1px solid var(--lc-border);
193
+ background: var(--lc-bg);
194
+ }
195
+
196
+ .aj-options-section + .aj-options-section {
197
+ margin-top: 12px;
198
+ }
199
+
200
+ .aj-options-section-title {
201
+ margin: 0 0 10px;
202
+ font-size: 11px;
203
+ font-weight: 700;
204
+ text-transform: uppercase;
205
+ letter-spacing: 0.06em;
206
+ color: var(--lc-muted);
207
+ }
208
+
209
+ .aj-options-section-title + .aj-field,
210
+ .aj-options-section-title + .aj-field-checkbox {
211
+ margin-top: 0;
212
+ }
213
+
214
  .aj-options-hint {
215
+ margin: 8px 0 0;
216
  font-size: 12px;
217
  color: var(--lc-muted);
218
  line-height: 1.45;
frontend/src/App.jsx CHANGED
@@ -1397,49 +1397,55 @@ export default function App() {
1397
  </button>
1398
  {optionsOpen && (
1399
  <div id="aj-options-panel" className="aj-options-panel" role="dialog" aria-label="Options" onMouseDown={(e) => e.stopPropagation()}>
1400
- <label className="aj-field">
1401
- <span>Additional persona instructions</span>
1402
- <textarea
1403
- value={extraPersona}
1404
- onChange={(e) => setExtraPersona(e.target.value)}
1405
- placeholder="Optional — style, tone, domain focus… The assistant stays AI Jerry."
1406
- rows={10}
1407
- disabled={streaming}
1408
- />
1409
- </label>
1410
- <p className="aj-options-hint">
1411
- Merged into the system prompt for this session. The chat label remains <strong>AI Jerry</strong>.
1412
- </p>
1413
- <label className="aj-field aj-field-checkbox">
1414
- <input
1415
- type="checkbox"
1416
- checked={alwaysSpeak}
1417
- onChange={(e) => setAlwaysSpeak(e.target.checked)}
1418
- disabled={streaming}
1419
- />
1420
- <span>Always speak responses</span>
1421
- </label>
1422
- <p className="aj-options-hint">
1423
- When enabled, each assistant reply is read aloud automatically after it finishes generating (uses text-to-speech).
1424
- </p>
1425
- <label className="aj-field">
1426
- <span>Playback speed</span>
1427
- <div className="aj-speed-options">
1428
- {TTS_SPEED_OPTIONS.map(s => (
1429
- <button
1430
- key={s}
1431
- type="button"
1432
- className={`aj-speed-option${ttsSpeed === s ? ' aj-speed-option--active' : ''}`}
1433
- onClick={() => setTtsSpeed(s)}
1434
- >
1435
- {s}x
1436
- </button>
1437
- ))}
1438
- </div>
1439
- </label>
1440
- <p className="aj-options-hint">
1441
- Controls how fast text-to-speech audio plays. Applies to all messages.
1442
- </p>
 
 
 
 
 
 
1443
  </div>
1444
  )}
1445
  </div>
 
1397
  </button>
1398
  {optionsOpen && (
1399
  <div id="aj-options-panel" className="aj-options-panel" role="dialog" aria-label="Options" onMouseDown={(e) => e.stopPropagation()}>
1400
+ <div className="aj-options-section">
1401
+ <h4 className="aj-options-section-title">Voice</h4>
1402
+ <label className="aj-field aj-field-checkbox">
1403
+ <input
1404
+ type="checkbox"
1405
+ checked={alwaysSpeak}
1406
+ onChange={(e) => setAlwaysSpeak(e.target.checked)}
1407
+ disabled={streaming}
1408
+ />
1409
+ <span>Always speak responses</span>
1410
+ </label>
1411
+ <p className="aj-options-hint">
1412
+ Read each assistant reply aloud automatically (text-to-speech).
1413
+ </p>
1414
+ <label className="aj-field">
1415
+ <span>Playback speed</span>
1416
+ <div className="aj-speed-options">
1417
+ {TTS_SPEED_OPTIONS.map(s => (
1418
+ <button
1419
+ key={s}
1420
+ type="button"
1421
+ className={`aj-speed-option${ttsSpeed === s ? ' aj-speed-option--active' : ''}`}
1422
+ onClick={() => setTtsSpeed(s)}
1423
+ >
1424
+ {s}x
1425
+ </button>
1426
+ ))}
1427
+ </div>
1428
+ </label>
1429
+ <p className="aj-options-hint">
1430
+ Controls how fast text-to-speech audio plays.
1431
+ </p>
1432
+ </div>
1433
+ <div className="aj-options-section">
1434
+ <h4 className="aj-options-section-title">Persona</h4>
1435
+ <label className="aj-field">
1436
+ <span>Additional persona instructions</span>
1437
+ <textarea
1438
+ value={extraPersona}
1439
+ onChange={(e) => setExtraPersona(e.target.value)}
1440
+ placeholder="Optional — style, tone, domain focus… The assistant stays AI Jerry."
1441
+ rows={10}
1442
+ disabled={streaming}
1443
+ />
1444
+ </label>
1445
+ <p className="aj-options-hint">
1446
+ Merged into the system prompt for this session. The chat label remains <strong>AI Jerry</strong>.
1447
+ </p>
1448
+ </div>
1449
  </div>
1450
  )}
1451
  </div>