Structural UI modernisation v1.39.0
Details
Replace the flat, corporate-feeling desktop shell with a modern, animated layout that feels premium across all seven themes.
**NavigationSidebar — full redesign**
- Gradient sidebar background (ThemeNavGradientBrush) replaces flat colour
- Left accent bar: wrapper Border uses BorderThickness="3,0,0,0" with BrushTransition from Transparent → ThemePrimaryBrush when the nav item is active — the VS Code / Linear active indicator pattern
- Icon bubble (Border.nav-icon-bubble): 28×28 rounded square inside each nav item transitions from transparent to ThemePrimaryMutedBrush on active; icon stroke transitions to ThemePrimaryBrush
- Workspace card header: replaces plain TextBlock with a full-width button containing a 28×28 icon bubble (Layers icon, ThemePrimaryMutedBrush), workspace name (SemiBold), "Workspace" subtitle, and ChevronsUpDown chevron — all with 120ms BrushTransitions
- All code-behind named elements preserved: ExpandedNavItems, CollapsedNavItems, DragOverlay, CollapsedTimerIndicator, CollapsedTimerPopup; drag-reorder logic intact
**SettingsPanel — two-column redesign with animated navigation**
- Replaced single-column accordion (12 Expanders) with a two-column Grid (190px / *)
- Left column: ListBox.settings-categories — 12 category items each with an icon bubble + label; selected item gets ThemePrimaryMutedBrush background and ThemePrimaryBrush icon/text with 120ms BrushTransition; Danger Zone uses danger-colour bubble
- Right column: Carousel (replaces TabControl) with CrossFade 150ms page transition — categories cross-fade when switching, giving a fluid animated feel
- Code-behind: removed accordion Expander logic entirely; OnCategoryListSelectionChanged syncs CategoryList.SelectedIndex → Carousel.SelectedIndex; OnLoaded/OnUnloaded wire and unwire the handler cleanly
- DataContext changes for Connections and CloudSync sections preserved with x:DataType on child StackPanels
**PrivStackTheme.axaml — hover lift animations**
- Border.hoverable: added TransformOperationsTransition (200ms CubicEaseOut) and BoxShadowsTransition; :pointerover now sets RenderTransform="translateY(-2px)" and a stronger BoxShadow — cards lift off the surface on hover
- Border.card: same lift treatment — translateY(-2px) + shadow deepens from 3px to 20px on hover; TransformOperationsTransition 200ms
- Border.stat-card: same hover lift applied — dashboard metric tiles rise on hover
All changes compile clean (0 errors, 0 warnings). Version bumped 1.38.0 → 1.39.0.
Redesign AI suggestion panel as multi-card list + fix table summarize (v1.45.0)
Details
Redesign the AI suggestion panel from a single-suggestion view to a multi-card
list with interactive expand/collapse, block navigation with flash animations,
inline action buttons (Replace, Insert Above/Below), and undo support. Cards
persist across panel close/reopen and are restored on page switch.
Fix ExtractBlockText to handle TableBlock (inline-backed only), DefinitionListBlock,
FootnoteBlock, ImageBlock, and ChartBlock — previously these returned empty strings,
causing AI Summarize to silently produce nothing for table blocks.
Add flash highlight animation to BlockWrapper (opacity-animated blue overlay) triggered
when expanding a suggestion card or applying an action. Wire RequestBlockFlash event
through NotesView for scroll-to-block + visual feedback.
Add PathIcon glyphs to all context menu items (AI, Summarize, Copy Link, Duplicate,
Delete) with accent color on hover for visual consistency.
AiSuggestionStore migrated from blockId-keyed to GUID-keyed entries to support
multiple suggestions per block, with undo state fields (OriginalBlockContent,
AppliedAction, InsertedBlockId).
Design system overhaul v1.38.0
Details
Comprehensive visual upgrade across the desktop shell targeting a modern, premium feel while preserving all existing functionality and the 7-theme token system.
## SharedTokens.axaml (new)
Extracted ~140 lines of duplicated layout constants (corner radii, spacing, font sizes, padding, panel widths, icon sizes, animation durations, EmptyState sizing tokens) into a single shared ResourceDictionary. All 7 theme files now include it via MergedDictionaries, eliminating the previous token duplication.
## Theme Files (all 7 updated)
- Dark, Light, Azure, Sage, Lavender: Added ThemeNavGradientBrush (subtle top→bottom depth on nav sidebar), ThemeNavAccentBarBrush (primary→secondary vertical gradient for active nav item accent bar), ThemePrimaryGradientBrush (tactile top-light depth on accent buttons). Nav gradient end colours are individually tuned per theme.
- Ember, Slate: Same gradient brushes, with hardcoded hex stops since these themes use ThemeSurface directly for their nav background rather than a dedicated ThemeNavBackground key.
- Removed all duplicate layout token blocks from each theme file (now sourced from SharedTokens).
## PrivStackTheme.axaml (major enhancements)
- Button.accent: Background changed to ThemePrimaryGradientBrush; pressed state adds scale(0.97) render transform for tactile feedback.
- New Button.icon-button (32×32, Padding=6) and Button.icon-button-lg (40×40, Padding=8) classes for compact icon-only actions.
- Border.card / Border.elevated-card / Border.surface-card: Stronger shadow values, added 1px ThemeBorderSubtleBrush border for depth.
- New Border.stat-card: Elevated surface with Padding=20, CornerRadius=ThemeRadiusLg, 1px border, card-level shadow. Used by Dashboard.
- New Border.nav-accent-bar: 3px wide, right-rounded (0,2,2,0), ThemeNavAccentBarBrush background. Used in NavigationSidebar.
- New Border.section-divider: 1px height divider using ThemeBorderSubtleBrush.
- Typography upgrades: TextBlock.subheading reduced to 11px with LetterSpacing=0.8 and SemiBold weight (category labels now look intentional); TextBlock.page-heading upgraded to Bold; new TextBlock.plugin-title (20px SemiBold), TextBlock.hero-number (34px Bold), TextBlock.empty-state-heading (22px SemiBold Center), TextBlock.empty-state-message (14px Muted Center Wrap).
- ListBoxItem: Added CornerRadius=ThemeRadiusSm.
- Button.view-toggle.active: Upgraded to iOS segmented-control style — ThemeSurfaceElevatedBrush background with subtle BoxShadow instead of flat selected colour.
- New Expander.settings-section style: ThemeSurfaceBrush background, ThemeRadiusLg corner radius, ThemeBorderSubtleBrush 1px border. Includes /template/ ToggleButton override for HorizontalContentAlignment=Stretch and Padding=16,14.
## NavigationSidebar.axaml
Sidebar container background changed from flat ThemeNavBackgroundBrush to ThemeNavGradientBrush for subtle depth that works across all themes.
## ViewToggleGroup.axaml
Outer container changed to ThemeSurfaceRecessedBrush + ThemeRadiusMd + Padding=3 to create the iOS segmented-control recessed track. Active tab uses ThemeSurfaceElevatedBrush with subtle drop shadow. Local styles updated with 120ms BrushTransitions on Background and Foreground.
## SettingsPanel.axaml
All 12 section expander headers updated with icon bubbles: 28×28 Border (CornerRadius=6, Background=ThemePrimaryMutedBrush) containing a 14px IconControl. Section→icon mapping: Profile=User, Appearance=Settings, Accessibility=AlertCircle, Notifications=Mail, Speech-to-Text=MessageSquare, Data & Backup=Database, Connections=Network, Cloud Sync=Sync, Security=Lock, Enterprise=Users, About=Info, Danger Zone=AlertCircle (ThemeDangerMutedBrush bubble + ThemeDangerBrush icon + ThemeDangerBrush text). Added xmlns:controls namespace to root element.
## DashboardView.axaml
System Overview cards (Overview tab) and Storage Overview cards (Data tab) both upgraded:
- Border now uses Classes="stat-card" for consistent elevation, border, and corner radius.
- Each card has a 40×40 icon bubble (CornerRadius=10) with semantic colour: App Shell/Database=ThemeInfo (blue), Plugins/Files=ThemeWarning (amber), Data Storage/Vault=ThemeSuccess (green), Memory/Total=ThemePrimary (accent).
- Large metric value TextBlock upgraded to Classes="hero-number" (34px Bold).
- Label and subtext reorganised into a nested StackPanel with Spacing=2 for cleaner visual grouping.
## Version
PrivStack.Desktop: 1.37.1 → 1.38.0 (minor bump for design system overhaul)
Add EmptyState control — v1.40.0
Details
Introduces a reusable `EmptyState` control to `PrivStack.UI.Adaptive`, eliminating
per-plugin ad-hoc "no items yet" implementations.
**What was added**
`Controls/EmptyState.cs` — a `Border` subclass following the established imperative
construction pattern (no AXAML template, no reflection bindings). All visual tokens
resolve dynamically from the active PrivStack theme via `GetResourceObservable`.
Properties exposed:
- `IconData` (Geometry?) — Material icon path supplied by the consumer.
- `Title` (string) — Primary heading displayed below the icon bubble.
- `Message` (string) — Supporting copy, center-aligned, max-width 320, wrapping.
- `ActionLabel` / `ActionCommand` — Optional primary CTA (renders as `Button.accent`,
hidden when ActionLabel is null or empty).
- `SecondaryActionLabel` / `SecondaryActionCommand` — Optional ghost CTA (renders as
`Button.ghost`, hidden when SecondaryActionLabel is null or empty).
- `Variant` (EmptyStateVariant enum: Default | Search | Error | Permission) — Controls
which theme brush pair is applied to the icon bubble background and icon fill.
Visual structure:
```
StackPanel (center, spacing=24)
Border (72×72, CornerRadius=20) ← icon bubble; color driven by Variant
Path (36×36, Stretch=Uniform) ← icon path
StackPanel (spacing=8)
TextBlock ← title (ThemeFontSizeHeading2, SemiBold, ThemeTextPrimaryBrush)
TextBlock ← message (ThemeFontSizeBody, ThemeTextMutedBrush, MaxWidth=320)
StackPanel (spacing=12) [hidden when no ActionLabel]
Button.accent ← primary CTA
Button.ghost ← secondary CTA [hidden when no SecondaryActionLabel]
```
Variant → brush mapping:
- Default → ThemePrimaryMutedBrush / ThemePrimaryBrush
- Search → ThemeInfoMutedBrush / ThemeInfoBrush
- Error → ThemeDangerMutedBrush / ThemeDangerBrush
- Permission → ThemeWarningMutedBrush / ThemeWarningBrush
Theme changes are handled by subscribing to `ActualThemeVariantChanged` in
`OnAttachedToVisualTree` and unsubscribing in `OnDetachedFromVisualTree`, matching
the lifecycle pattern used by `PluginToolbar`, `PluginSidebar`, and `IconLabel`.
**Version bump**
`Directory.Build.props`: `PrivStackSdkVersion` 1.39.0 → 1.40.0
This is a minor bump reflecting new additive API surface in `PrivStack.UI.Adaptive`.
No breaking changes to existing controls.
Add AI task-to-note conversion feature (v1.9.0)
Details
Add AI-powered "Create Note from Task" context menu action to the task
detail panel. When invoked, TaskToNoteService gathers the full task
context (title, description, status, priority, dates, subtasks,
checklist, time entries, linked items resolved via ILinkableItemProvider)
and sends it to the configured AI provider. The AI generates a
structured Markdown note which is then created as a page in the Notes
plugin via the SDK message bus, preserving plugin isolation. Navigation
automatically redirects to the newly created note.
New files:
- TaskToNoteService.cs: Orchestrates context gathering, AI call, page
creation via SdkMessage, and navigation
- TasksViewModel.AI.cs: Partial class exposing IsAiAvailable and
ConvertToNoteCommand, wired by TasksPlugin when Host.AI is available
Modified files:
- TasksPlugin.cs: Wires AI service to ViewModel in CreateViewModelCore
- TaskDetailPanel.axaml.cs: Adds context menu with AI > Create Note
from Task item, visibility gated on IsAiAvailable
- PrivStack.Plugin.Tasks.csproj: Version bump 1.8.4 → 1.9.0
Get notified about new releases