// After:
```
**CSS:**
```css
.peach-canary-card {
border: 1px solid rgba(217, 160, 48, 0.2);
background: rgba(217, 160, 48, 0.03);
border-radius: 8px;
padding: 12px;
}
.peach-canary-settings-header {
display: flex;
align-items: center;
justify-content: space-between;
cursor: pointer;
user-select: none;
}
.peach-canary-card .peach-label {
color: rgba(217, 160, 48, 0.85);
}
.peach-canary-card .peach-new-field-input {
border-color: rgba(217, 160, 48, 0.25);
}
.peach-canary-card .peach-new-field-input:focus {
border-color: rgba(217, 160, 48, 0.5);
}
.peach-canary-body {
margin-top: 12px;
display: flex;
flex-direction: column;
gap: 10px;
}
.peach-canary-hint {
font-size: 10px;
color: var(--t2);
font-family: var(--font-ui);
line-height: 1.5;
margin-top: 4px;
}
.peach-canary-actions-row {
display: flex;
align-items: center;
gap: 8px;
}
.peach-canary-test-btn {
border-color: rgba(217, 160, 48, 0.3);
color: rgba(217, 160, 48, 0.85);
}
.peach-canary-test-result {
font-size: 10px;
font-family: var(--font-ui);
}
.peach-canary-test-result.ok { color: rgba(100, 210, 100, 0.9); }
.peach-canary-test-result.err { color: rgba(220, 80, 60, 0.9); }
```
Remove all the matching inline styles from Add.tsx and replace with the class names above.
### 4c. Note entry form
The note form (`selectedType() === "note"`) renders just a textarea with `style="min-height:200px;"`. It needs:
- A proper `.peach-note-form` container with consistent padding
- The textarea to use a class `peach-note-textarea` with appropriate sizing
- A character count hint in the bottom-right corner (`{notes().length} chars`)
```css
.peach-note-textarea {
width: 100%;
min-height: 180px;
max-height: 280px;
resize: vertical;
background: var(--t4);
border: 1px solid var(--t3);
border-radius: 8px;
padding: 10px 12px;
font-family: var(--font-mono);
font-size: 12px;
line-height: 1.7;
color: var(--t1);
outline: none;
transition: border-color 150ms ease;
}
.peach-note-textarea:focus {
border-color: var(--t2);
}
.peach-note-char-count {
font-family: var(--font-mono);
font-size: 9px;
color: var(--t3);
text-align: right;
margin-top: 4px;
letter-spacing: 0.1em;
}
```
### 4d. Field input baseline
All `peach-new-field-input` and `peach-new-name-input` elements need consistent focus rings and a visible resting border. Currently they likely inherit nothing or use browser defaults. Define:
```css
.peach-new-field-input {
width: 100%;
background: transparent;
border: none;
border-bottom: 1px solid var(--t3);
padding: 4px 0;
color: var(--t1);
font-family: var(--font-mono);
font-size: 13px;
outline: none;
transition: border-color 150ms ease;
}
.peach-new-field-input:focus {
border-bottom-color: var(--t1);
color: var(--t0);
}
.peach-new-name-input {
width: 100%;
background: transparent;
border: none;
border-bottom: 1px solid var(--t3);
padding: 6px 0;
font-family: var(--font-display);
font-style: italic;
font-size: 28px;
color: var(--t0);
outline: none;
transition: border-color 150ms ease;
}
.peach-new-name-input:focus {
border-bottom-color: var(--t1);
}
.peach-new-name-input::placeholder {
color: var(--t2);
font-style: italic;
}
.peach-new-field-input::placeholder {
color: var(--t3);
}
```
---
## 5. Remove the standalone Generator navigation path from Add.tsx
In `App.tsx`, the `"generator"` view is reachable from Add via `onOpenGenerator`. Once the drawer is in place, the Add form no longer needs this prop. The `"generator"` view from the main vault toolbar (the wand/sparkle button) remains available — that's a valid standalone use. Just remove it as a destination from Add's `onBack`/`onOpenGenerator` flow.
In `App.tsx`:
- Remove the `openGenerator` function call that sets view to `"generator"` when coming from Add
- AddView no longer receives `onOpenGenerator` prop
- The `GeneratorView` standalone entry point from the toolbar is preserved
---
## 6. General surface cohesion items
### 6a. Overlay headers
All overlay views (Add, Health, CJKExport, etc.) share `.peach-overlay-header`. Make sure the cancel/back button on the left and the action button on the right are always vertically centered and have consistent spacing. Audit that no overlay header has a different height from any other.
```css
.peach-overlay-header {
display: flex;
align-items: center;
justify-content: space-between;
padding: 10px 16px;
border-bottom: 1px solid var(--t3);
flex-shrink: 0;
min-height: 44px; /* lock the height */
}
.peach-overlay-title {
font-family: var(--font-mono);
font-size: 10px;
letter-spacing: 0.18em;
text-transform: uppercase;
color: var(--t1);
position: absolute;
left: 50%;
transform: translateX(-50%);
}
.peach-overlay-action {
position: relative;
z-index: 1;
min-width: 44px; /* prevent layout shift as label changes */
text-align: center;
}
```
### 6b. Scrollable body overflow
Any overlay body that can exceed 520px (Add.tsx with all fields, Health with many entries) must be scrollable within the popup, not invisible below the fold. The body element must not overflow the popup frame.
```css
.peach-overlay-view {
display: flex;
flex-direction: column;
height: 520px; /* match popup height exactly */
overflow: hidden;
}
.peach-overlay-body,
.peach-add-form,
.peach-health-body,
.peach-pwgen-body {
flex: 1;
overflow-y: auto;
overflow-x: hidden;
overscroll-behavior: contain;
scrollbar-width: thin;
scrollbar-color: var(--t3) transparent;
padding: 14px 16px;
}
```
This is the fix for long passwords rendering off-screen — the symptom is actually the container not scrolling, not the password field itself overflowing.
### 6c. Toggle component
The `.peach-toggle` / `.peach-toggle-knob` pattern is used in Generator, Settings, and Canary. Add a consistent `transition` so the knob slides smoothly:
```css
.peach-toggle {
position: relative;
width: 28px;
height: 16px;
border-radius: 8px;
background: var(--t3);
border: none;
cursor: pointer;
flex-shrink: 0;
transition: background 200ms ease;
}
.peach-toggle.is-on {
background: var(--peach-accent);
}
.peach-toggle-knob {
position: absolute;
top: 2px;
left: 2px;
width: 12px;
height: 12px;
border-radius: 50%;
background: var(--t0);
transition: transform 200ms var(--peach-curve-settle);
}
.peach-toggle.is-on .peach-toggle-knob {
transform: translateX(12px);
}
```
### 6d. Button states
Every `peach-btn` needs a `:focus-visible` ring that doesn't use the browser default outline (which looks wrong on the dark background):
```css
.peach-btn:focus-visible {
outline: none;
box-shadow: 0 0 0 2px var(--bg), 0 0 0 4px rgba(217, 104, 48, 0.5);
}
```
### 6e. Scrollbar in Vault list
The vault entry list scrollbar is currently browser-default (visible and ugly on Windows/Linux). Add:
```css
.peach-vault-list {
scrollbar-width: thin;
scrollbar-color: var(--t3) transparent;
}
.peach-vault-list::-webkit-scrollbar {
width: 3px;
}
.peach-vault-list::-webkit-scrollbar-thumb {
background: var(--t3);
border-radius: 2px;
}
```
---
## 7. File change summary
| File | Changes |
|------|---------|
| `src/popup/styles/popup.css` | Remove root border-radius; add `.lock-screen--unlock`, `.lock-centered`, `.peach-lock-restore-link`, `.peach-restore-sheet`, `.peach-type-tabs`, `.peach-type-tab`, `.peach-canary-card` and all child classes, `.peach-note-textarea`, `.peach-new-field-input`, `.peach-new-name-input`, `.peach-generator-drawer`, `.peach-pwgen-output` overflow fix, `.peach-overlay-*` height lock, scrollbar polish, toggle transition, focus-visible rings |
| `src/popup/views/Lock.tsx` | Two distinct layouts: unlock (password only, nothing else) and onboarding (create + two flat restore links); delete `restoreSurface` signal, secondary panel, and all restore code from unlock path |
| `src/popup/views/Settings.tsx` | Add "Vault" section with "Replace vault from backup" — disclaimer card + CJK and file restore paths behind a destructive-action confirmation |
| `src/popup/views/Add.tsx` | Remove `onOpenGenerator` prop; add `showGenerator` signal; inline ``; replace canary inline styles with classes; replace note textarea with `peach-note-textarea` class + char count; replace type tab inline styles |
| `src/popup/components/GeneratorDrawer.tsx` | New file — extracts generator logic as a collapsible inline drawer |
| `src/popup/views/Generator.tsx` | No changes — remains available standalone from vault toolbar |
| `src/popup/App.tsx` | Remove `openGenerator` as Add destination; keep it as toolbar destination |
---
## 8. What this is NOT
- Not a redesign. Every color, every font, every animation curve stays.
- Not feature work. No new functionality.
- Not a theme change. The amber/bone palette is correct.
- Not a layout overhaul of the vault list or entry view — those are polished. Touch only the surfaces called out above.