Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion app/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -831,7 +831,7 @@ def account_preferences():
valid_themes = {
'glass', 'retro', 'solar', 'paper', 'noir',
'arctic-ice', 'rose-gold', 'cyberpunk-neon',
'emerald-matrix', 'obsidian',
'emerald-matrix', 'obsidian', 'rack-console',
}
if (
not isinstance(data['theme'], str)
Expand Down
3 changes: 2 additions & 1 deletion app/socket_events.py
Original file line number Diff line number Diff line change
Expand Up @@ -1664,7 +1664,8 @@ def handle_set_theme(data, current_user=None):
theme = data.get('theme')
valid_themes = [
'glass', 'retro', 'solar', 'paper', 'noir',
'arctic-ice', 'rose-gold', 'cyberpunk-neon', 'emerald-matrix', 'obsidian'
'arctic-ice', 'rose-gold', 'cyberpunk-neon', 'emerald-matrix', 'obsidian',
'rack-console'
]
if theme not in valid_themes:
emit('error', {'error': 'Invalid theme'})
Expand Down
53 changes: 53 additions & 0 deletions design-qa.md
Original file line number Diff line number Diff line change
Expand Up @@ -252,3 +252,56 @@ and context navigation no longer compete in one toolbar.
- Remaining P0/P1/P2 findings: none.

final result: passed

## Rack Console theme QA (2026-09-03)

### Reference and rendered evidence

- Source visual truth: `/home/heimdall/.codex/generated_images/01a065f7-4668-7430-b372-d629f24bbab0/exec-964d13f7-b9c8-4d59-8050-762296fee235.png` (1672 x 941 px), the selected Rack Console concept.
- Browser-rendered implementation: `/tmp/webssh-rack-console-design-qa/rack-console-implementation-final.png` (1280 x 720 px) at a 1280 x 720 CSS viewport.
- Density normalization: the in-app browser reported `devicePixelRatio: 2` but returned a CSS-pixel screenshot. The source was proportionally normalized to 1280 x 720 for comparison; its aspect ratio differs only by source rounding.
- State: authenticated seeded administrator, Rack Console selected through Settings, Workspaces active, saved hosts visible, Notes open, and no active SSH session.
- Full-view comparison: `/tmp/webssh-rack-console-design-qa/rack-console-comparison-final.png` places the normalized source and final implementation side by side.
- Focused top-rail comparison: `/tmp/webssh-rack-console-design-qa/rack-console-top-comparison-final.png` compares navigation, brand, session controls, borders, and active states at readable scale.
- Focused workspace comparison: `/tmp/webssh-rack-console-design-qa/rack-console-workspace-comparison-final.png` compares the host surface, rack rows, right service module, and bottom telemetry rail.
- Responsive supporting evidence: `/tmp/webssh-rack-console-design-qa/rack-console-mobile.png` and `/tmp/webssh-rack-console-design-qa/rack-console-mobile-menu-v2.png` at 390 x 844 CSS px.

### Fidelity review

- Fonts and typography: the implementation preserves WebSSH's shared Inter hierarchy for readable product copy and applies IBM Plex Mono selectively to rack labels, navigation, controls, endpoints, notes, and telemetry. Uppercase labels and restrained tracking reproduce the source's equipment-label character without changing content width or the global type system.
- Spacing and layout rhythm: header, session rail, main content, terminal grid, context workspace, and status bar retain the existing application arrangement. The final comparison preserves the same 1280 x 720 document width with no horizontal overflow. Thicker inner bezels consume only their own box and do not move the major regions.
- Colors and visual tokens: warm graphite surfaces (`#08090a` through `#22262a`), warm off-white text, and one restrained amber accent replace the previous blue-gray treatment. Header faceplate, session rail, recessed terminal, right service module, note well, and bottom telemetry rail have distinct surface treatments rather than sharing one repeated background.
- Image quality and asset fidelity: the theme uses the generated 1586 x 992 gunmetal texture at low opacity inside the recessed terminal and on the authentication dock. It remains sharp at the tested viewport, has no transparency halo or stretched subject, and is not used as a substitute for icons or controls. Existing WebSSH and Material Icons assets remain intact.
- Copy and content: existing product labels, host names, endpoint details, actions, Notes copy, and status text are unchanged. The implementation does not introduce the mockup's illustrative rack IDs because the selected concept was a visual direction and the user explicitly required the existing arrangement to remain intact.
- Icons and controls: existing icon semantics are retained. Buttons, tabs, inputs, host rows, dialogs, and mobile actions share the 2-4 px rack geometry and inset tactile treatment, while active state, success, warning, and destructive colors remain distinguishable.
- Accessibility and resilience: muted text remains covered by the existing 4.5:1 theme regression; keyboard focus uses the brighter amber focus token. Desktop and 390 x 844 mobile states have no horizontal overflow. The mobile action sheet, search, saved connection actions, Quick Connect dialog, and panel close action remain usable.

### Primary interactions and runtime checks

- Selected Rack Console through the authenticated Settings flow and verified persistence after returning to Workspaces.
- Filtered saved connections through the host search and restored the full list.
- Opened and closed Quick Connect, verified the dialog remained contained, and preserved existing form behavior.
- Opened the mobile More sheet at 390 x 844 and verified every visible navigation and session action remained contained.
- Compared Glass and Rack Console in the same authenticated state: header, session rail, main content, terminal grid, and right context workspace retain their major geometry and the host grid keeps the same track count.
- Browser console warnings and errors after the final desktop path: none.

### Comparison history

#### Pass 1

- P1: the right-panel close control inherited IBM Plex Mono and rendered the word `close` beyond its 34 px control instead of the Material Icons glyph. Fixed by restoring the Material Icons family and normal letter spacing specifically on `.context-workspace-close`.
- P2: the mobile More sheet retained the generic 14 px rounded container and looked unrelated to the rack controls around it. Fixed with the Rack Console faceplate, 3 px shell radius, inset highlight, and 2 px mobile control radii.

#### Pass 2

- P2: the first rack header and session rail added outer borders that increased the combined header by 2 px and the session rail by 1 px. Fixed by retaining the existing single header divider and expressing the additional depth with inset shadows; the final header, toolbar, and main-content measurements match Glass exactly.
- P2: the visual hierarchy was initially too flat compared with the selected faceplate direction. Fixed with a restrained graphite header gradient while keeping the terminal texture, right service surface, and status rail materially distinct.

#### Final pass

- The normalized full-view and focused comparisons show the selected industrial direction in the existing WebSSH structure: equipment-like rails, square tactile controls, recessed work area, rack-style host rows, a separately treated service module, and segmented telemetry status.
- The source's illustrative corner screws, diagonal chassis cuts, and invented row-ID plates are intentionally not reproduced. They would add decorative assets or content that does not exist in the product and would conflict with the no-rearrangement constraint.
- Remaining P0/P1/P2 findings: none.
- Optional P3 polish: a future purpose-built nine-slice chassis asset could add subtle physical corner hardware if the product later adopts that ornament globally; it is not required for this theme to preserve cohesion or usability.

final result: passed
55 changes: 55 additions & 0 deletions static/css/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -542,6 +542,61 @@ body[data-theme="obsidian"] {
--theme-background-opacity: 0.055;
}

body[data-theme="rack-console"] {
--bg-primary: #08090a;
--bg-secondary: #101214;
--bg-tertiary: #171a1d;
--bg-hover: #22262a;
--bg-modal: rgba(10, 11, 12, 0.985);
--bg-gradient: linear-gradient(145deg, #08090a 0%, #151719 100%);
--bg-active: rgba(215, 132, 47, 0.14);
--text-primary: #eeece7;
--text-secondary: #bbb8b1;
--text-muted: #8f8c85;
--border-color: rgba(224, 220, 211, 0.15);
--border-hover: rgba(224, 220, 211, 0.29);
--accent-primary: #d7842f;
--accent-primary-glow: rgba(215, 132, 47, 0.2);
--accent-secondary: #9b968c;
--accent-tertiary: #68a47c;
--success-color: #6db486;
--warning-color: #d99a48;
--error-color: #da6d66;
--info-color: #9ba7b3;
--btn-primary-gradient-end: #aa5f1c;
--btn-primary-text: #0a0b0c;
--btn-primary-shadow: rgba(215, 132, 47, 0.16);
--btn-primary-shadow-hover: rgba(215, 132, 47, 0.26);
--accent-on-text: #0a0b0c;
--shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.54);
--shadow-md: 0 5px 14px rgba(0, 0, 0, 0.54);
--shadow-lg: 0 12px 30px rgba(0, 0, 0, 0.62);
--shadow-glow: 0 0 14px rgba(215, 132, 47, 0.12);
--term-background: #090a0b;
--term-foreground: #e7e4de;
--term-black: #202326;
--term-red: #d66f68;
--term-green: #70b58a;
--term-yellow: #d99a48;
--term-blue: #8ea4b8;
--term-magenta: #af8fa5;
--term-cyan: #81aaa6;
--term-white: #d5d2cb;
--term-bright-black: #55595d;
--term-bright-red: #e68a83;
--term-bright-green: #91caa5;
--term-bright-yellow: #e9b66d;
--term-bright-blue: #abc0d1;
--term-bright-magenta: #c8a9be;
--term-bright-cyan: #9dc3bf;
--term-bright-white: #ffffff;
--theme-background-image-source: url("../images/theme-backgrounds/rack-console-gunmetal.png?v=5373b8b77cc681b4");
--theme-background-opacity: 0.085;
--theme-surface-shell: rgba(13, 14, 15, 0.92);
--theme-surface-modal: rgba(10, 11, 12, 0.94);
--theme-surface-card: rgba(18, 20, 22, 0.9);
}

body:is([data-theme="glass"], [data-theme="solar"], [data-theme="paper"], [data-theme="noir"], [data-theme="arctic-ice"], [data-theme="rose-gold"], [data-theme="obsidian"]) .main-content,
body:is([data-theme="glass"], [data-theme="solar"], [data-theme="paper"], [data-theme="noir"], [data-theme="arctic-ice"], [data-theme="rose-gold"], [data-theme="obsidian"]) .terminal-pane {
background-image: var(--theme-background-image);
Expand Down
Loading
Loading