Skip to content

Commit 148ca8b

Browse files
Tomer Vakninclaude
andcommitted
Modernize UI with design token system, polished cards, tabs, and animations
- Add DesignTokens.xaml with semantic color/spacing/typography tokens - Redesign host list with card-based layout, hover actions, tag chips - Polish session tabs with pill style, accent indicator, hover animations - Enhance welcome panel with pulse ring animations and info cards - Modernize settings dialog sidebar with Windows 11-style nav indicators Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 0d4fc11 commit 148ca8b

6 files changed

Lines changed: 1185 additions & 508 deletions

File tree

src/SshManager.App/App.xaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
<ResourceDictionary.MergedDictionaries>
99
<ui:ThemesDictionary Theme="Dark" />
1010
<ui:ControlsDictionary />
11+
<ResourceDictionary Source="Styles/DesignTokens.xaml" />
1112
<ResourceDictionary Source="Styles/Animations.xaml" />
1213
<ResourceDictionary Source="Styles/Converters.xaml" />
1314
<ResourceDictionary Source="Styles/TerminalTheme.xaml" />
Lines changed: 251 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,251 @@
1+
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
2+
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
3+
xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml">
4+
5+
<!--
6+
Design Token System for SshManager
7+
Semantic color tokens that adapt to WPF-UI's theme system.
8+
Use these instead of hardcoded hex values throughout the app.
9+
-->
10+
11+
<!-- ═══════════════════════════════════════════════════════════════
12+
SURFACE TOKENS — backgrounds and layering
13+
═══════════════════════════════════════════════════════════════ -->
14+
<SolidColorBrush x:Key="SurfaceBaseBrush" Color="{DynamicResource SolidBackgroundFillColorBase}" />
15+
<SolidColorBrush x:Key="SurfaceLayerBrush" Color="{DynamicResource LayerFillColorDefault}" />
16+
<SolidColorBrush x:Key="SurfaceCardBrush" Color="{DynamicResource CardBackgroundFillColorDefault}" />
17+
<SolidColorBrush x:Key="SurfaceCardHoverBrush" Color="{DynamicResource CardBackgroundFillColorSecondary}" />
18+
<SolidColorBrush x:Key="SurfaceSmokeBrush" Color="{DynamicResource SmokeFillColorDefault}" />
19+
<SolidColorBrush x:Key="SurfaceSubtleBrush" Color="{DynamicResource SubtleFillColorTransparent}" />
20+
<SolidColorBrush x:Key="SurfaceSubtleHoverBrush" Color="{DynamicResource SubtleFillColorSecondary}" />
21+
<SolidColorBrush x:Key="SurfaceSubtlePressedBrush" Color="{DynamicResource SubtleFillColorTertiary}" />
22+
23+
<!-- ═══════════════════════════════════════════════════════════════
24+
CONTROL TOKENS — interactive elements
25+
═══════════════════════════════════════════════════════════════ -->
26+
<SolidColorBrush x:Key="ControlDefaultBrush" Color="{DynamicResource ControlFillColorDefault}" />
27+
<SolidColorBrush x:Key="ControlSecondaryBrush" Color="{DynamicResource ControlFillColorSecondary}" />
28+
<SolidColorBrush x:Key="ControlTertiaryBrush" Color="{DynamicResource ControlFillColorTertiary}" />
29+
<SolidColorBrush x:Key="ControlDisabledBrush" Color="{DynamicResource ControlFillColorDisabled}" />
30+
<SolidColorBrush x:Key="ControlInputActiveBrush" Color="{DynamicResource ControlFillColorInputActive}" />
31+
32+
<!-- ═══════════════════════════════════════════════════════════════
33+
TEXT TOKENS — foreground colors
34+
═══════════════════════════════════════════════════════════════ -->
35+
<SolidColorBrush x:Key="TextPrimaryBrush" Color="{DynamicResource TextFillColorPrimary}" />
36+
<SolidColorBrush x:Key="TextSecondaryBrush" Color="{DynamicResource TextFillColorSecondary}" />
37+
<SolidColorBrush x:Key="TextTertiaryBrush" Color="{DynamicResource TextFillColorTertiary}" />
38+
<SolidColorBrush x:Key="TextDisabledBrush" Color="{DynamicResource TextFillColorDisabled}" />
39+
<SolidColorBrush x:Key="TextOnAccentBrush" Color="{DynamicResource TextOnAccentFillColorPrimary}" />
40+
41+
<!-- ═══════════════════════════════════════════════════════════════
42+
STROKE TOKENS — borders and dividers
43+
═══════════════════════════════════════════════════════════════ -->
44+
<SolidColorBrush x:Key="StrokeDefaultBrush" Color="{DynamicResource ControlStrokeColorDefault}" />
45+
<SolidColorBrush x:Key="StrokeSecondaryBrush" Color="{DynamicResource ControlStrokeColorSecondary}" />
46+
<SolidColorBrush x:Key="StrokeDividerBrush" Color="{DynamicResource DividerStrokeColorDefault}" />
47+
<SolidColorBrush x:Key="StrokeSurfaceBrush" Color="{DynamicResource CardStrokeColorDefault}" />
48+
49+
<!-- ═══════════════════════════════════════════════════════════════
50+
ACCENT TOKENS — brand and interactive accent colors
51+
═══════════════════════════════════════════════════════════════ -->
52+
<SolidColorBrush x:Key="AccentPrimaryBrush" Color="{DynamicResource SystemAccentColorPrimary}" />
53+
<SolidColorBrush x:Key="AccentSecondaryBrush" Color="{DynamicResource SystemAccentColorSecondary}" />
54+
<SolidColorBrush x:Key="AccentTertiaryBrush" Color="{DynamicResource SystemAccentColorTertiary}" />
55+
<!-- Fallback accent for environments where system accent isn't available -->
56+
<Color x:Key="AccentBlue">#0078D4</Color>
57+
<Color x:Key="AccentBlueDark">#106EBE</Color>
58+
<Color x:Key="AccentBlueLight">#60CDFF</Color>
59+
<SolidColorBrush x:Key="AccentBlueBrush" Color="{StaticResource AccentBlue}" />
60+
61+
<!-- ═══════════════════════════════════════════════════════════════
62+
SEMANTIC STATUS TOKENS — contextual status colors
63+
═══════════════════════════════════════════════════════════════ -->
64+
65+
<!-- Success / Connected -->
66+
<Color x:Key="StatusSuccessColor">#4CAF50</Color>
67+
<Color x:Key="StatusSuccessSubtleColor">#204CAF50</Color>
68+
<SolidColorBrush x:Key="StatusSuccessBrush" Color="{StaticResource StatusSuccessColor}" />
69+
<SolidColorBrush x:Key="StatusSuccessSubtleBrush" Color="{StaticResource StatusSuccessSubtleColor}" />
70+
71+
<!-- Warning -->
72+
<Color x:Key="StatusWarningColor">#FF9800</Color>
73+
<Color x:Key="StatusWarningSubtleColor">#20FF9800</Color>
74+
<SolidColorBrush x:Key="StatusWarningBrush" Color="{StaticResource StatusWarningColor}" />
75+
<SolidColorBrush x:Key="StatusWarningSubtleBrush" Color="{StaticResource StatusWarningSubtleColor}" />
76+
77+
<!-- Error / Danger -->
78+
<Color x:Key="StatusErrorColor">#E81123</Color>
79+
<Color x:Key="StatusErrorSubtleColor">#20E81123</Color>
80+
<SolidColorBrush x:Key="StatusErrorBrush" Color="{StaticResource StatusErrorColor}" />
81+
<SolidColorBrush x:Key="StatusErrorSubtleBrush" Color="{StaticResource StatusErrorSubtleColor}" />
82+
83+
<!-- Info -->
84+
<Color x:Key="StatusInfoColor">#2196F3</Color>
85+
<Color x:Key="StatusInfoSubtleColor">#202196F3</Color>
86+
<SolidColorBrush x:Key="StatusInfoBrush" Color="{StaticResource StatusInfoColor}" />
87+
<SolidColorBrush x:Key="StatusInfoSubtleBrush" Color="{StaticResource StatusInfoSubtleColor}" />
88+
89+
<!-- Neutral / Disconnected -->
90+
<Color x:Key="StatusNeutralColor">#999999</Color>
91+
<SolidColorBrush x:Key="StatusNeutralBrush" Color="{StaticResource StatusNeutralColor}" />
92+
93+
<!-- ═══════════════════════════════════════════════════════════════
94+
ELEVATION TOKENS — card shadows and depth
95+
═══════════════════════════════════════════════════════════════ -->
96+
<DropShadowEffect x:Key="ElevationNone" BlurRadius="0" ShadowDepth="0" Opacity="0" />
97+
<DropShadowEffect x:Key="ElevationLow" BlurRadius="8" ShadowDepth="2" Opacity="0.16" Color="#000000" />
98+
<DropShadowEffect x:Key="ElevationMedium" BlurRadius="16" ShadowDepth="4" Opacity="0.22" Color="#000000" />
99+
<DropShadowEffect x:Key="ElevationHigh" BlurRadius="24" ShadowDepth="8" Opacity="0.30" Color="#000000" />
100+
101+
<!-- ═══════════════════════════════════════════════════════════════
102+
SPACING TOKENS — consistent spacing scale
103+
═══════════════════════════════════════════════════════════════ -->
104+
<Thickness x:Key="SpacingXxs">2</Thickness>
105+
<Thickness x:Key="SpacingXs">4</Thickness>
106+
<Thickness x:Key="SpacingSm">8</Thickness>
107+
<Thickness x:Key="SpacingMd">12</Thickness>
108+
<Thickness x:Key="SpacingLg">16</Thickness>
109+
<Thickness x:Key="SpacingXl">24</Thickness>
110+
<Thickness x:Key="SpacingXxl">32</Thickness>
111+
112+
<!-- Card spacing patterns -->
113+
<Thickness x:Key="CardPadding">12</Thickness>
114+
<Thickness x:Key="CardMargin">4,2</Thickness>
115+
<CornerRadius x:Key="CardCornerRadius">8</CornerRadius>
116+
<CornerRadius x:Key="CardCornerRadiusLg">12</CornerRadius>
117+
<CornerRadius x:Key="PillCornerRadius">20</CornerRadius>
118+
<CornerRadius x:Key="RoundCornerRadius">6</CornerRadius>
119+
120+
<!-- ═══════════════════════════════════════════════════════════════
121+
TYPOGRAPHY TOKENS — font family, sizes, weights
122+
═══════════════════════════════════════════════════════════════ -->
123+
124+
<!-- Primary font: Segoe UI Variable (Win11), fallback to Segoe UI -->
125+
<FontFamily x:Key="AppFontFamily">Segoe UI Variable, Segoe UI, sans-serif</FontFamily>
126+
<FontFamily x:Key="MonoFontFamily">Cascadia Code, Cascadia Mono, Consolas, monospace</FontFamily>
127+
128+
<!-- Type scale -->
129+
<system:Double x:Key="TypeCaption" xmlns:system="clr-namespace:System;assembly=mscorlib">11</system:Double>
130+
<system:Double x:Key="TypeBody" xmlns:system="clr-namespace:System;assembly=mscorlib">13</system:Double>
131+
<system:Double x:Key="TypeBodyLarge" xmlns:system="clr-namespace:System;assembly=mscorlib">14</system:Double>
132+
<system:Double x:Key="TypeSubtitle" xmlns:system="clr-namespace:System;assembly=mscorlib">16</system:Double>
133+
<system:Double x:Key="TypeTitle" xmlns:system="clr-namespace:System;assembly=mscorlib">20</system:Double>
134+
<system:Double x:Key="TypeTitleLarge" xmlns:system="clr-namespace:System;assembly=mscorlib">24</system:Double>
135+
<system:Double x:Key="TypeDisplay" xmlns:system="clr-namespace:System;assembly=mscorlib">28</system:Double>
136+
137+
<!-- ═══════════════════════════════════════════════════════════════
138+
TYPOGRAPHY STYLES — reusable text styles
139+
═══════════════════════════════════════════════════════════════ -->
140+
<Style x:Key="CaptionText" TargetType="TextBlock">
141+
<Setter Property="FontFamily" Value="{StaticResource AppFontFamily}" />
142+
<Setter Property="FontSize" Value="{StaticResource TypeCaption}" />
143+
<Setter Property="Foreground" Value="{DynamicResource TextSecondaryBrush}" />
144+
</Style>
145+
146+
<Style x:Key="BodyText" TargetType="TextBlock">
147+
<Setter Property="FontFamily" Value="{StaticResource AppFontFamily}" />
148+
<Setter Property="FontSize" Value="{StaticResource TypeBody}" />
149+
<Setter Property="Foreground" Value="{DynamicResource TextPrimaryBrush}" />
150+
</Style>
151+
152+
<Style x:Key="BodyStrongText" TargetType="TextBlock">
153+
<Setter Property="FontFamily" Value="{StaticResource AppFontFamily}" />
154+
<Setter Property="FontSize" Value="{StaticResource TypeBody}" />
155+
<Setter Property="FontWeight" Value="SemiBold" />
156+
<Setter Property="Foreground" Value="{DynamicResource TextPrimaryBrush}" />
157+
</Style>
158+
159+
<Style x:Key="SubtitleText" TargetType="TextBlock">
160+
<Setter Property="FontFamily" Value="{StaticResource AppFontFamily}" />
161+
<Setter Property="FontSize" Value="{StaticResource TypeSubtitle}" />
162+
<Setter Property="FontWeight" Value="SemiBold" />
163+
<Setter Property="Foreground" Value="{DynamicResource TextPrimaryBrush}" />
164+
</Style>
165+
166+
<Style x:Key="TitleText" TargetType="TextBlock">
167+
<Setter Property="FontFamily" Value="{StaticResource AppFontFamily}" />
168+
<Setter Property="FontSize" Value="{StaticResource TypeTitle}" />
169+
<Setter Property="FontWeight" Value="SemiBold" />
170+
<Setter Property="Foreground" Value="{DynamicResource TextPrimaryBrush}" />
171+
</Style>
172+
173+
<Style x:Key="DisplayText" TargetType="TextBlock">
174+
<Setter Property="FontFamily" Value="{StaticResource AppFontFamily}" />
175+
<Setter Property="FontSize" Value="{StaticResource TypeDisplay}" />
176+
<Setter Property="FontWeight" Value="Light" />
177+
<Setter Property="Foreground" Value="{DynamicResource TextPrimaryBrush}" />
178+
</Style>
179+
180+
<Style x:Key="MonoText" TargetType="TextBlock">
181+
<Setter Property="FontFamily" Value="{StaticResource MonoFontFamily}" />
182+
<Setter Property="FontSize" Value="{StaticResource TypeCaption}" />
183+
<Setter Property="Foreground" Value="{DynamicResource TextSecondaryBrush}" />
184+
</Style>
185+
186+
<!-- ═══════════════════════════════════════════════════════════════
187+
COMMON ELEMENT STYLES — reusable UI patterns
188+
═══════════════════════════════════════════════════════════════ -->
189+
190+
<!-- Section header with accent left border (Windows 11 Settings style) -->
191+
<Style x:Key="SectionHeader" TargetType="Border">
192+
<Setter Property="BorderBrush" Value="{DynamicResource AccentPrimaryBrush}" />
193+
<Setter Property="BorderThickness" Value="3,0,0,0" />
194+
<Setter Property="Padding" Value="12,4,0,4" />
195+
<Setter Property="Margin" Value="0,16,0,8" />
196+
</Style>
197+
198+
<!-- Subtle card container -->
199+
<Style x:Key="SubtleCard" TargetType="Border">
200+
<Setter Property="Background" Value="{DynamicResource SurfaceCardBrush}" />
201+
<Setter Property="BorderBrush" Value="{DynamicResource StrokeSurfaceBrush}" />
202+
<Setter Property="BorderThickness" Value="1" />
203+
<Setter Property="CornerRadius" Value="{StaticResource CardCornerRadius}" />
204+
<Setter Property="Padding" Value="{StaticResource CardPadding}" />
205+
</Style>
206+
207+
<!-- Interactive card with hover effect -->
208+
<Style x:Key="InteractiveCard" TargetType="Border">
209+
<Setter Property="Background" Value="{DynamicResource SurfaceCardBrush}" />
210+
<Setter Property="BorderBrush" Value="{DynamicResource StrokeSurfaceBrush}" />
211+
<Setter Property="BorderThickness" Value="1" />
212+
<Setter Property="CornerRadius" Value="{StaticResource CardCornerRadius}" />
213+
<Setter Property="Padding" Value="{StaticResource CardPadding}" />
214+
<Setter Property="Cursor" Value="Hand" />
215+
<Style.Triggers>
216+
<Trigger Property="IsMouseOver" Value="True">
217+
<Setter Property="Background" Value="{DynamicResource SurfaceCardHoverBrush}" />
218+
<Setter Property="BorderBrush" Value="{DynamicResource StrokeDefaultBrush}" />
219+
</Trigger>
220+
</Style.Triggers>
221+
</Style>
222+
223+
<!-- Badge/chip base style -->
224+
<Style x:Key="ChipBadge" TargetType="Border">
225+
<Setter Property="CornerRadius" Value="{StaticResource PillCornerRadius}" />
226+
<Setter Property="Padding" Value="8,3" />
227+
<Setter Property="Background" Value="{DynamicResource SurfaceSubtleBrush}" />
228+
<Setter Property="BorderBrush" Value="{DynamicResource StrokeSecondaryBrush}" />
229+
<Setter Property="BorderThickness" Value="1" />
230+
</Style>
231+
232+
<!-- Keyboard shortcut hint badge -->
233+
<Style x:Key="KeyboardHint" TargetType="Border">
234+
<Setter Property="Background" Value="{DynamicResource ControlSecondaryBrush}" />
235+
<Setter Property="CornerRadius" Value="4" />
236+
<Setter Property="Padding" Value="6,2" />
237+
<Setter Property="BorderBrush" Value="{DynamicResource StrokeSecondaryBrush}" />
238+
<Setter Property="BorderThickness" Value="1" />
239+
</Style>
240+
241+
<!-- Navigation item indicator (active state left bar) -->
242+
<Style x:Key="NavIndicator" TargetType="Border">
243+
<Setter Property="Width" Value="3" />
244+
<Setter Property="Height" Value="16" />
245+
<Setter Property="CornerRadius" Value="2" />
246+
<Setter Property="Background" Value="{DynamicResource AccentPrimaryBrush}" />
247+
<Setter Property="VerticalAlignment" Value="Center" />
248+
<Setter Property="Visibility" Value="Collapsed" />
249+
</Style>
250+
251+
</ResourceDictionary>

0 commit comments

Comments
 (0)