Bundles patina palette shift, logo update (translucent gradient gem), glass-card vocabulary across login/setup/fullscreen, and the original two-column form layout. Updates relicario-logo.svg and -16.svg to the patina palette. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
15 KiB
Phase 2B: Polish Foundation + Form Layout
Date: 2026-05-02
Status: Spec, awaiting review
Surface: Browser extension — popup, fullscreen vault, setup wizard
Parent spec: docs/superpowers/specs/2026-04-30-relicario-fullscreen-ux-redesign-design.md
Goal
Bring the extension up to a "professional, contained" feel — like opening 1Password or another polished password manager — without losing the terminal-monospace soul. Three surfaces (login popup, setup wizard, fullscreen vault) all get the same polish vocabulary applied. Phase 2B also lands the two-column login form layout from the parent spec.
What changed from the original Phase 2B scope
The original Phase 2B was scoped to form layout only. After visual review, we expanded scope to include:
- A patina palette shift — gold accent dialed from bright
#d2ab43toward weathered#a88a4a/#cdb47a/#5a3f12. Red theca dialed from saturated#9a1a1atoward brick#7d2622. - Logo update — same composition, patina palette, translucent gradient gem.
- Polish vocabulary — backdrop with subtle radial glow + 18px grid texture, glass cards (translucent panels with backdrop-blur), refined typography lockup, primary/secondary button hierarchy.
- Arrow glyph —
▸(U+25B8) for "next" buttons, matching the▾/▸disclosure glyphs already in use.
These items now ship together so the form layout lands inside an already-polished surface, rather than as a layout change inside flat CSS.
Non-goals
- Three-pane shell, keyboard nav, command palette — deferred to Phase 3.
- New affordances — Phase 2A already shipped the 8 smart inputs.
- Light theme — single dark theme stays.
- Mobile/narrow layouts under 720px — popup handles narrow.
- Animated transitions / motion — focus state is the only transition.
- Item types other than
logingetting a two-column treatment.
Visual language
The polish vocabulary lives in extension/src/popup/styles.css and extension/src/vault/vault.css. Both files share token definitions and class names where possible.
Palette (patina)
:root {
/* Patina gold — replaces the bright amber */
--gold-base: #a88a4a; /* base, less yellow / more bronze */
--gold-mid: #cdb47a; /* duller mid-highlight */
--gold-shadow: #5a3f12; /* deeper bronze shadow */
--gold-text: #c9a868; /* legible on dark, brand text */
--gold-soft: rgba(184,149,86,0.14); /* hover/active fill */
--gold-ring: rgba(184,149,86,0.18); /* focus ring */
--gold-stroke: #b89556; /* default border on emphasized elements */
/* Surface — slightly deeper than current bg */
--bg-base: #0a0e14; /* page (was #0d1117) */
--bg-pane: #11161e; /* slightly elevated surface */
--bg-card: rgba(22, 27, 34, 0.55); /* glass card fill */
--bg-input: #0a0e14; /* matches base for sunken feel */
/* Borders */
--border-soft: rgba(255,255,255,0.05); /* card edges */
--border-mid: #262d36; /* input borders */
--border-warm: #2a3140; /* slightly warmer for vault.css */
/* Text */
--text: #c9d1d9;
--text-muted: #8b949e;
--text-dim: #6b7888;
}
The bright accent token --accent: #d2ab43 is renamed to --gold-base: #a88a4a. Aliases keep existing component code working during the migration (--accent: var(--gold-base)).
Backdrop
A reusable backdrop applied to popup body, setup wizard body, and the vault shell:
.surface-backdrop {
position: relative;
background:
radial-gradient(ellipse 700px 240px at 50% -40px, rgba(184,149,86,0.05), transparent 65%),
linear-gradient(180deg, #11161e 0%, #0a0e14 100%);
}
.surface-backdrop::before {
content: '';
position: absolute;
inset: 0;
background-image:
linear-gradient(rgba(255,255,255,0.012) 1px, transparent 1px),
linear-gradient(90deg, rgba(255,255,255,0.012) 1px, transparent 1px);
background-size: 18px 18px;
pointer-events: none;
}
.surface-backdrop > * { position: relative; z-index: 1; }
The radial top-glow opacity is intentionally low (0.05) so it doesn't wash out on cheaper monitors. The grid texture is barely visible (0.012 white) — adds a sense of "place" without becoming busy.
Glass card
Used for the unlock card, setup step card, mode-picker cards, and form section cards (Identity / Credentials):
.glass {
background: rgba(22, 27, 34, 0.55);
backdrop-filter: blur(8px);
-webkit-backdrop-filter: blur(8px);
border: 1px solid rgba(255,255,255,0.05);
border-radius: 10px;
box-shadow:
0 1px 0 rgba(255,255,255,0.03) inset,
0 6px 18px rgba(0,0,0,0.35);
}
Browsers without backdrop-filter support fall back gracefully — the card stays semi-translucent over the backdrop without the blur.
Buttons
Two clear tiers:
.btn-primary {
background: var(--gold-base);
color: var(--bg-base);
border: none;
padding: 9px 14px;
font-size: 12px;
font-weight: 600;
border-radius: 6px;
letter-spacing: 0.3px;
}
.btn-primary:hover { background: #c9a868; }
.btn-secondary {
background: transparent;
border: 1px solid rgba(255,255,255,0.06);
color: var(--text-muted);
padding: 6px 12px;
font-size: 11px;
border-radius: 5px;
}
Existing .btn class keeps existing styling for backwards compatibility; new .btn-primary / .btn-secondary are used in updated views.
Typography lockup
Logo + brand + tagline group with tighter spacing on login and setup:
- Logo mark: 40-44px square, 9-10px corner radius, inner highlight only (no outer glow).
- Brand text: weight 600, color
var(--gold-text), letter-spacing 0.5px. - Tagline: 11px,
var(--text-dim), letter-spacing 0.3px.
Inputs
.input {
background: var(--bg-input);
border: 1px solid var(--border-mid);
color: var(--text);
padding: 9px 10px;
border-radius: 6px;
transition: border-color 0.15s, box-shadow 0.15s;
}
.input:focus {
outline: none;
border-color: var(--gold-stroke);
box-shadow: 0 0 0 2px var(--gold-ring);
}
Arrow glyph
The ▸ (U+25B8, small right triangle) replaces ASCII → in "next" buttons. Reuses the existing disclosure-glyph vocabulary already used in ▾ custom sections / ▸ attachments.
Logo update
extension/icons/relicario-logo.svg and extension/icons/relicario-logo-16.svg updated:
- Gold gradient stops shifted:
#d2ab43 → #f5d97a → #7c5719becomes#a88a4a → #cdb47a → #5a3f12. - Red theca radial:
#9a1a1a → #3a0a0abecomes#7d2622 → #2c0d0a. - Highlight gradient:
#fde9a8 → #d2ab43becomes#dac8a0 → #a88a4a. - Solid gold tones (
#7c5719,#fff3cf,#8a5e1c) remapped to patina equivalents. - Center asterisk gem now translucent: facets use vertical gradients (
gemFacetLight/gemFacetDark) that fade to transparent at the tip; gem core uses a radial glass gradient (gemCore); two refraction highlights replace the single white-yellow dot.
The composition (pedestal, theca, gem, hinge collar, fleur-de-lis) is unchanged.
Surface-by-surface changes
Login popup (extension/src/popup/)
unlock.ts view:
┌──────────────────────────────────┐
│ [logo] │
│ Relicario │
│ two-factor vault │
│ │
│ ┌─[ glass card ]──────────────┐ │
│ │ UNLOCK │ │
│ │ [passphrase input ] │ │
│ │ [ unlock vault ] │ │ ← btn-primary, full width
│ └──────────────────────────────┘ │
│ │
│ [open vault] [settings] │ ← btn-secondary, demoted
└──────────────────────────────────┘
- Body gets
.surface-backdrop. - Logo lockup grouped (logo / brand / tagline) with tighter spacing (8-12px between).
- Form moves into
.glasscard withUNLOCKlabel inside. - Primary action is a real button ("unlock vault") — replaces the "press Enter to submit" implicit flow.
- Open-vault and settings demoted to secondary buttons below the card.
Setup wizard (extension/src/setup/)
- Body gets
.surface-backdrop. - Header lockup at top (logo + "Relicario vault setup").
- Progress dots get a tiny shadow on the current step (
box-shadow: 0 0 4px rgba(184,149,86,0.4)). - Each
wizard-stepbecomes a.glasscard. - Mode-picker cards become smaller
.glasscards with patina active state. - All "next" buttons use
▸glyph.
Fullscreen vault (extension/src/vault/)
- Body gets
.surface-backdrop. - Form section panels (Identity, Credentials) are
.glasscards. - Save bar matches glass treatment with translucent fill + backdrop-blur.
- Form layout switches to two-column for login (see below).
Form layout (login, fullscreen only)
The original Phase 2B scope:
┌────────────────────────────────────────────────────────────┐
│ edit login ⌘+S to save │
│ unsaved · esc to cancel │
├──────────────────────────┬─────────────────────────────────┤
│ [ glass: IDENTITY ] │ [ glass: CREDENTIALS ] │
│ title [required] │ username │
│ url + ⤓ │ password ⊙ ↻ │
│ group (autocomplete) │ strength: ████░ │
│ │ totp secret ◫ │
│ │ live: 492 837 · 23s │
├──────────────────────────┴─────────────────────────────────┤
│ NOTES │
│ ▾ custom sections ▸ attachments │
├────────────────────────────────────────────────────────────┤
│ STICKY SAVE BAR [cancel] [save] │
└────────────────────────────────────────────────────────────┘
Layout rules
- Form pane content:
max-width: 960px,margin: 0 auto. - Two-column wrapper:
display: grid; grid-template-columns: 1fr 1fr; gap: 24px;. - Below 720px viewport:
grid-template-columns: 1fr(single column stack). - Notes / custom sections / attachments live in a sibling block below the grid, full-width.
Column assignment (login)
Left column — IDENTITY:
- title (required pill)
- url +
⤓fill-from-tab button + hostname chip below - group input + datalist autocomplete
Right column — CREDENTIALS:
- username
- password +
⊙reveal +↻generate; strength bar below the input - totp secret +
◫QR button; live preview below the input
Full-width below grid:
- notes (with
≡mono toggle) - custom sections / fields disclosure
- attachments disclosure
Sticky save bar
position: sticky; bottom: 0;inside the form pane scroll container.- Translucent fill matching the glass vocabulary, with a 24px gradient fade above (content scrolls under).
- Right-aligned
[cancel] [save]buttons. - Save button reflects validity state — disabled when required fields are empty.
Header treatment
- Title (left):
new login/edit login, weight 500, size 18px. - Subtitle (left, below title):
unsaved · esc to cancel(dirty) orno changes(pristine),var(--text-muted), size 12px. - Hint (right):
⌘+S to save(visual only — actual save shortcut arrives in Phase 3 keymap),var(--text-dim), size 12px. RendersCtrl+Son non-mac. - Popout-to-tab
⤴removed from fullscreen forms (already done in Phase 1).
Other item types
Single-column stays for secure_note, identity, card, key, totp, document. They still get the new glass-card treatment around the form section, sticky save bar, and header treatment — only the column grid is login-specific.
Files touched
| File | Change |
|---|---|
extension/icons/relicario-logo.svg |
Patina palette + gradient glass gem |
extension/icons/relicario-logo-16.svg |
Patina palette (toolbar size) |
extension/src/popup/styles.css |
Patina tokens, .surface-backdrop, .glass, .btn-primary/secondary |
extension/src/popup/components/unlock.ts |
Logo lockup, glass card, primary unlock button |
extension/src/popup/components/types/login.ts |
Add surface: 'popup' | 'fullscreen' param; column wrapping when fullscreen |
extension/src/setup/setup.ts |
.surface-backdrop, glass step cards, glass mode-picker cards, ▸ arrows |
extension/src/setup/setup.html |
Body wrapper class |
extension/src/vault/vault.css |
Patina tokens, glass form sections, form-grid, sticky save bar, header treatment |
extension/src/vault/vault.ts |
Header subtitle dirty-state subscriber, surface flag passed to login renderer |
extension/src/vault/components/*.ts |
Glass class on form panels |
The login renderer needs to know which surface it's rendering into (popup vs fullscreen). Add an optional surface: 'popup' | 'fullscreen' parameter to renderForm(). Default to popup to preserve existing behavior.
Testing
Per-area tests using existing vitest + happy-dom setup:
- Palette migration test: computed style on
.btn-primaryresolves to#a88a4a. - Layout test: mount login form with
surface: 'fullscreen', assert grid layout, Identity / Credentials columns contain expected fields. - Stack-down test: simulate viewport ≤720px, assert single-column.
- Dirty subtitle test: mount form, simulate input, assert subtitle text changes.
- Sticky bar test: assert save bar exists, position style, save button validity.
- Glass class application: unlock card, setup step card, form panels all get
.glassclass. - Arrow glyph test: all "next" buttons render
▸(no→). - Other-type non-regression: mount
secure_note, assert single-column layout. - Logo regression: snapshot test on
relicario-logo.svgdefs/colors.
Manual QA pass per surface with the rebuilt extension loaded in Chrome and Firefox.
CLI parity
This phase is purely visual / layout-shaped. No CLI counterpart. The CLI already accepts all login fields as flags (--title, --username, --password, etc.).
Out of scope / deferred
- Two-column layout for non-login types.
- User-resizable column widths.
- Animated transitions on subtitle text change (snap is fine).
- Functional ⌘+S keyboard shortcut — arrives with Phase 3 keymap. The hint is a visual label until then.
- Diff view / form-level "you changed N fields" indicator.
- Light theme.