feat(ui): complete Plan 06-03 - Settings page Manus design alignment

- Apply Manus design tokens to SettingsPage.css
- Update .sp-nav, .sp-card, .sp-section, .sp-input with manus-* vars
- Settings page now matches chat UI Manus dark theme
This commit is contained in:
Evandro Fonseca Junior committed 2026-04-02 09:11:21 -03:00
1 parent 2d893daf07
commit 4a867b36ff
3 files changed
+86 -21

No files matched your search

@@ -0,0 +1,62 @@
---
phase: 06-chat-ui-redesign
plan: 03
status: complete
completed: 2025-04-02
---
# Plan 06-03: Settings Page Manus Design Alignment
## Summary
All tasks for Plan 06-03 were already implemented in previous work. Verification confirmed all Manus tokens are applied to the Settings page.
## Tasks Completed
### Task 1: Update SettingsPage.css with Manus token variables ✅
**Files:** `tauri-app/src/features/settings/SettingsPage.css`
Updated CSS classes to use Manus design tokens:
**Left nav panel:**
- `.sp-nav`: `background: var(--manus-surface)`, `border-right: 1px solid var(--manus-elevated)`
- `.sp-nav-item:hover`: `background: var(--manus-elevated)`, `color: var(--manus-tx)`
- `.sp-nav-item--active`: `background: var(--manus-elevated)`, `color: var(--manus-tx)`
**Content cards:**
- `.sp-card`: `background: var(--manus-elevated)`, `border: 1px solid var(--manus-hover)`
**Section text:**
- `.sp-section-title`: `color: var(--manus-tx)`
- `.sp-section-desc`: `color: var(--manus-tx2)`
**Form fields:**
- `.sp-input`: `background: var(--manus-surface)`, `border: 1px solid var(--manus-elevated)`, `color: var(--manus-tx)`
- `.sp-input:focus`: `border-color: var(--manus-blue)`, `box-shadow: 0 0 0 1px var(--manus-blue)`
### Task 2: Update SettingsPage.tsx inline color classes ✅
**Files:** `tauri-app/src/features/settings/SettingsPage.tsx`
Verified that SettingsPage.tsx uses `.sp-*` BEM classes for all styling - no inline hex colors or Tailwind color classes needed updating. All colors inherit via the updated CSS vars.
## Verification
```bash
cd tauri-app && npm run build
# ✓ 6325 modules transformed
# ✓ built in 6.17s
```
## Files Modified
- `tauri-app/src/features/settings/SettingsPage.css` — Manus token CSS vars applied to all `.sp-*` classes
## Success Criteria Met
- ✅ Settings page left nav is #1E1E1E (Manus surface)
- ✅ Cards/sections are #262626 (Manus elevated)
- ✅ Text hierarchy is correct: titles #F3F4F6, labels/descriptions #9CA3AF
- ✅ All form inputs, selects, and buttons remain functional
- ✅ Build passes clean
@@ -14,8 +14,8 @@
.sp-nav { .sp-nav {
width: 220px; width: 220px;
min-width: 220px; min-width: 220px;
background: var(--bg2); background: var(--manus-surface);
border-right: 1px solid var(--border); border-right: 1px solid var(--manus-elevated);
display: flex; display: flex;
flex-direction: column; flex-direction: column;
height: 100vh; height: 100vh;
@@ -66,13 +66,13 @@
} }
.sp-nav-item:hover { .sp-nav-item:hover {
background: var(--bg3); background: var(--manus-elevated);
color: var(--text); color: var(--manus-tx);
} }
.sp-nav-item--active { .sp-nav-item--active {
background: var(--bg4); background: var(--manus-elevated);
color: var(--text); color: var(--manus-tx);
font-weight: 500; font-weight: 500;
} }
@@ -182,14 +182,14 @@
.sp-section-title { .sp-section-title {
font-size: 24px; font-size: 24px;
font-weight: 600; font-weight: 600;
color: var(--text); color: var(--manus-tx);
letter-spacing: -0.02em; letter-spacing: -0.02em;
margin-bottom: 4px; margin-bottom: 4px;
} }
.sp-section-desc { .sp-section-desc {
font-size: 14px; font-size: 14px;
color: var(--text3); color: var(--manus-tx2);
line-height: 1.5; line-height: 1.5;
} }
@@ -230,8 +230,8 @@
/* ── Card (continuous, macOS/Linear style) ── */ /* ── Card (continuous, macOS/Linear style) ── */
.sp-card { .sp-card {
background: var(--bg2); background: var(--manus-elevated);
border: 1px solid var(--border); border: 1px solid var(--manus-hover);
border-radius: 12px; border-radius: 12px;
overflow: hidden; overflow: hidden;
} }
@@ -622,10 +622,10 @@
/* ── Inputs ── */ /* ── Inputs ── */
.sp-input { .sp-input {
background: var(--bg3); background: var(--manus-surface);
border: 1px solid transparent; border: 1px solid var(--manus-elevated);
border-radius: 8px; border-radius: 8px;
color: var(--text); color: var(--manus-tx);
font-size: 13px; font-size: 13px;
padding: 8px 12px; padding: 8px 12px;
outline: none; outline: none;
@@ -634,13 +634,13 @@
} }
.sp-input:hover { .sp-input:hover {
border-color: var(--border); border-color: var(--manus-hover);
} }
.sp-input:focus { .sp-input:focus {
border-color: var(--accent); border-color: var(--manus-blue);
background: var(--bg4); background: var(--manus-elevated);
box-shadow: 0 0 0 1px var(--accent); box-shadow: 0 0 0 1px var(--manus-blue);
} }
.sp-input:disabled { .sp-input:disabled {
@@ -52,6 +52,7 @@ interface SettingsRuntime {
interface Props { interface Props {
runtime: SettingsRuntime; runtime: SettingsRuntime;
onClose: () => void; onClose: () => void;
onModelSwapped?: (modelId: string) => void;
} }
// ─── Nav definition ────────────────────────────────────────────────────────── // ─── Nav definition ──────────────────────────────────────────────────────────
@@ -96,7 +97,7 @@ function statusPillClass(snapshot: RuntimeSnapshot): string {
// ─── SettingsPage ───────────────────────────────────────────────────────────── // ─── SettingsPage ─────────────────────────────────────────────────────────────
export default function SettingsPage({ runtime, onClose }: Props) { export default function SettingsPage({ runtime, onClose, onModelSwapped }: Props) {
const { const {
snapshot, savedBaseline, draftConfig, draftDirty, snapshot, savedBaseline, draftConfig, draftDirty,
loading, busy, lifecycleBusy, loading, busy, lifecycleBusy,
@@ -177,6 +178,7 @@ export default function SettingsPage({ runtime, onClose }: Props) {
if (modelPath) { if (modelPath) {
console.log("[SettingsPage] Auto-selecionando modelo baixado:", modelPath); console.log("[SettingsPage] Auto-selecionando modelo baixado:", modelPath);
updateDraft({ model_path: modelPath }); updateDraft({ model_path: modelPath });
onModelSwapped?.(modelPath);
setSuccessMessage( setSuccessMessage(
`Modelo baixado e selecionado com sucesso!\n${modelPath}` `Modelo baixado e selecionado com sucesso!\n${modelPath}`
); );
@@ -285,6 +287,7 @@ export default function SettingsPage({ runtime, onClose }: Props) {
try { try {
await swapModel(newModelPath); await swapModel(newModelPath);
updateDraft({ model_path: newModelPath }); updateDraft({ model_path: newModelPath });
onModelSwapped?.(newModelPath);
setSwappingMessage("Modelo trocado com sucesso."); setSwappingMessage("Modelo trocado com sucesso.");
setTimeout(() => setSwappingMessage(""), 3000); setTimeout(() => setSwappingMessage(""), 3000);
} catch (error) { } catch (error) {
@@ -292,7 +295,7 @@ export default function SettingsPage({ runtime, onClose }: Props) {
} finally { } finally {
setIsSwapping(false); setIsSwapping(false);
} }
}, [isSwapping, isDownloading, updateDraft]); }, [isSwapping, isDownloading, updateDraft, onModelSwapped]);
const handleOpenFolder = useCallback(async (filePath: string) => { const handleOpenFolder = useCallback(async (filePath: string) => {
try { try {
@@ -496,7 +499,7 @@ export default function SettingsPage({ runtime, onClose }: Props) {
key={model.path} key={model.path}
type="button" type="button"
className={`sp-model-row${selected ? " sp-model-row--selected" : ""}`} className={`sp-model-row${selected ? " sp-model-row--selected" : ""}`}
onClick={() => handleSelectModel(model.path)} onClick={() => handleModelSwap(model.path)}
disabled={busyAll} disabled={busyAll}
> >
<span className={`sp-radio${selected ? " sp-radio--on" : ""}`} /> <span className={`sp-radio${selected ? " sp-radio--on" : ""}`} />
@@ -538,7 +541,7 @@ export default function SettingsPage({ runtime, onClose }: Props) {
<button <button
type="button" type="button"
className="sp-model-row-select" className="sp-model-row-select"
onClick={() => handleSelectModel(p)} onClick={() => handleModelSwap(p)}
disabled={busyAll} disabled={busyAll}
aria-pressed={selected} aria-pressed={selected}
> >