diff --git a/.planning/research/SUMMARY.md b/.planning/research/SUMMARY.md
index c8112e3..f8043d6 100644
--- a/.planning/research/SUMMARY.md
+++ b/.planning/research/SUMMARY.md
@@ -2,6 +2,349 @@
**Project:** SharePoint Toolbox — C#/WPF SharePoint Online Administration Desktop Tool
**Domain:** SharePoint Online administration, auditing, and provisioning (MSP / IT admin)
+**Researched:** 2026-04-02 (v1.0 original) | 2026-04-08 (v2.2 addendum)
+**Confidence:** HIGH
+
+---
+
+> **Note:** This file contains two sections. The original v1.0 research summary is preserved below
+> the v2.2 section. The roadmapper should consume **v2.2 first** for the current milestone.
+
+---
+
+# v2.2 Research Summary — Report Branding & User Directory
+
+**Milestone:** v2.2 — HTML Report Branding (MSP/client logos) + User Directory Browse Mode
+**Synthesized:** 2026-04-08
+**Sources:** STACK.md (v2.2 addendum), FEATURES.md (v2.2), ARCHITECTURE.md (v2.2), PITFALLS.md (v2.2 addendum)
+
+---
+
+## Executive Summary
+
+v2.2 adds two independent, self-contained features to a mature WPF MVVM codebase: logo branding
+across all five HTML export services, and a full-directory browse mode as an alternative to the
+existing people-picker in the User Access Audit tab. Both features are well within the capabilities
+of the existing stack — no new NuGet packages are required. The implementation path is low risk
+because neither feature touches the audit execution engine; they are purely additive layers on top
+of proven infrastructure.
+
+The branding feature follows a single clear pattern: store logos as base64 strings in existing JSON
+settings and profile files, pass them at export time via a new optional `ReportBranding` record, and
+inject `
` tags into a shared HTML header block. The architecture keeps the five export
+services independent (each receives an optional parameter) while avoiding code duplication through a
+shared header builder. The user directory browse feature adds a new `IGraphUserDirectoryService`
+alongside the existing search service, wires it to new ViewModel state in
+`UserAccessAuditViewModel`, and presents it as a toggle-panel in the View. The existing audit
+pipeline is completely untouched.
+
+The primary risks are not technical complexity but execution discipline: logo size must be enforced
+at import time (512 KB limit) to prevent HTML report bloat, Graph pagination must use `PageIterator`
+to handle tenants with more than 999 users, and logo data must be stored as base64 strings (not file
+paths) to ensure portability across machines. All three of these are straightforward to implement
+once the storage strategy is decided and locked in at the beginning of each feature's implementation
+phase.
+
+---
+
+## Key Findings
+
+### Stack Additions — None Required
+
+The entire v2.2 scope is served by the existing stack:
+
+| Capability | Provided By | Notes |
+|---|---|---|
+| Logo encoding (file → base64) | BCL `Convert.ToBase64String` + `File.ReadAllBytesAsync` | Zero new packages |
+| Logo preview in WPF settings UI | `BitmapImage` (WPF PresentationCore, already a transitive dep) | Standard WPF pattern |
+| Logo file picker | `OpenFileDialog` (WPF Microsoft.Win32, already used in codebase) | Filter to PNG/JPG/GIF/BMP |
+| User directory listing with pagination | `Microsoft.Graph` 5.74.0 `PageIterator` | Already installed |
+| Local directory filtering | `ICollectionView.Filter` (WPF System.Windows.Data) | Already used in PermissionsViewModel |
+| Logo + profile JSON persistence | `System.Text.Json` + existing Repository pattern | Backward-compatible nullable fields |
+
+Do NOT add: HTML template engines (Razor/Scriban), image processing libraries (ImageSharp,
+Magick.NET), or PDF export libraries. All explicitly out of scope.
+
+---
+
+### Feature Table Stakes vs. Differentiators
+
+**Feature 1: HTML Report Branding**
+
+Table stakes (must ship):
+- MSP global logo in every HTML report header
+- Client (per-tenant) logo in report header
+- Logo renders without external URL (data-URI embedding for self-contained HTML portability)
+- Graceful absence — no broken image icon when logo is not configured
+- Consistent placement across all five HTML export types
+
+Differentiators (build after table stakes):
+- Auto-pull client logo from Microsoft Entra tenant branding (`GET /organization/{id}/branding/localizations/default/bannerLogo`) — zero-config path using the existing `User.Read` delegated scope
+- Report timestamp and tenant display name in header
+
+Anti-features — do not build:
+- Per-tenant CSS color themes (design system complexity, disproportionate to MSP value)
+- PDF export with embedded logo (requires third-party binary dependency)
+- SVG logo support (XSS risk in data-URIs; PNG/JPG/GIF/BMP only)
+- Hotlinked logo URL field (breaks offline/archived reports)
+
+**Feature 2: User Directory Browse Mode**
+
+Table stakes (must ship):
+- Full directory listing (all enabled member users) with pagination
+- In-memory text filter on DisplayName/UPN/Mail without server round-trips
+- Sortable columns (Name, UPN)
+- Select user from list to trigger existing audit pipeline
+- Loading indicator with user count feedback ("Loaded X users...")
+- Toggle between Browse mode and Search (people-picker) mode
+
+Differentiators (add after core browse is stable):
+- Filter by account type (member vs. guest toggle)
+- Department / Job Title columns
+- Session-scoped directory cache (invalidated on tenant switch)
+
+Anti-features — do not build:
+- Eager load on tab open (large tenants block UI and risk throttling)
+- Delta query / incremental sync (wrong pattern for single-session audit)
+- Multi-user bulk simultaneous audit (different results model, out of scope)
+- Export user directory to CSV (identity reporting, not access audit)
+
+**Recommended MVP build order:**
+1. MSP logo in all HTML reports — highest visible impact, lowest complexity
+2. Client logo in HTML reports (import from file) — completes co-branding
+3. User directory browse core (load, select, filter, pipe into audit)
+4. Auto-pull client logo from Entra branding — add after file import path is proven
+5. Directory guest filter + department/jobTitle columns — low-effort polish
+
+---
+
+### Architecture Integration Points and Build Order
+
+**New files to create (7):**
+
+| Component | Layer | Purpose |
+|---|---|---|
+| `Core/Models/BrandingSettings.cs` | Core/Models | MSP logo base64 + MIME type; global, persisted in `branding.json` |
+| `Core/Models/ReportBranding.cs` | Core/Models | Lightweight record assembled at export time; NOT persisted |
+| `Core/Models/PagedUserResult.cs` | Core/Models | Page of `GraphUserResult` items + next-page cursor token |
+| `Infrastructure/Persistence/BrandingRepository.cs` | Infrastructure | Atomic JSON write (mirrors SettingsRepository pattern exactly) |
+| `Services/BrandingService.cs` | Services | Orchestrates file read → MIME detect → base64 → save |
+| `Services/IGraphUserDirectoryService.cs` | Services | Contract for paginated tenant user enumeration |
+| `Services/GraphUserDirectoryService.cs` | Services | Graph API user listing with `PageIterator` cursor pagination |
+
+**Existing files to modify (17), by risk level:**
+
+Medium risk (left-panel restructure or new async command):
+- `ViewModels/Tabs/UserAccessAuditViewModel.cs` — add `IGraphUserDirectoryService` injection + browse mode state/commands
+- `Views/Tabs/UserAccessAuditView.xaml` — add mode toggle + browse panel in left column
+
+Low risk (optional param or uniform inject-and-call pattern, batchable):
+- All 5 `Services/Export/*HtmlExportService.cs` — add `ReportBranding? branding = null` optional parameter
+- `PermissionsViewModel`, `StorageViewModel`, `SearchViewModel`, `DuplicatesViewModel` — add `BrandingService` injection + use in `ExportHtmlAsync`
+- `SettingsViewModel.cs` — add MSP logo browse/preview/clear commands
+- `ProfileManagementViewModel.cs` — add client logo browse/preview/clear commands
+- `SettingsView.xaml`, `ProfileManagementDialog.xaml` — add logo UI sections
+- `App.xaml.cs` — register 3 new services
+
+**Dependency-aware build phases:**
+
+| Phase | Scope | Risk | Gate |
+|---|---|---|---|
+| A — Models | BrandingSettings, ReportBranding, PagedUserResult, TenantProfile logo fields | None | POCOs; no dependencies |
+| B — Services | BrandingRepository, BrandingService, IGraphUserDirectoryService, GraphUserDirectoryService | Low | Unit-testable with mocks; Phase A required |
+| C — Export services | Add optional `ReportBranding?` to all 5 HTML export services | Low | Phase A required; regression tests: null branding produces identical HTML |
+| D — Branding ViewModels | SettingsVM, ProfileManagementVM, 4 export VMs, App.xaml.cs registration | Low | Phase B+C required; steps are identical pattern, batch them |
+| E — Directory ViewModel | UserAccessAuditViewModel browse mode state + commands | Medium | Phase B required; do after branding ViewModel pattern is proven |
+| F — Branding Views | SettingsView.xaml, ProfileManagementDialog.xaml, base64→BitmapSource converter | Low | Phase D required; write converter once, reuse in both views |
+| G — Directory View | UserAccessAuditView.xaml + code-behind SelectionChanged handler | Medium | Phase E required; do last, after ViewModel unit tests pass |
+
+Key architectural constraints (must not violate):
+- **Client logo on `TenantProfile`, NOT in `BrandingSettings`.** Client logos are per-tenant; mixing them with global MSP settings makes per-profile deletion and serialization awkward.
+- **Logos stored as base64 strings in JSON, not as file paths.** File paths become stale when the tool is redistributed to another machine. Decided once at Phase A; all downstream phases depend on it.
+- **Export services use optional `ReportBranding?` parameter, not required.** All existing call sites compile unchanged; branding is injected only where desired.
+- **No `IHtmlExportService` interface for this change.** The existing 5-concrete-classes pattern needs no interface for an optional parameter addition.
+- **`GraphUserDirectoryService` is a new service, separate from `GraphUserSearchService`.** Different call patterns (no `startsWith` filter, different pagination), different cancellation needs.
+- **Do NOT load the directory automatically on tab open.** Require explicit "Load Directory" button click to avoid blocking UI on large tenants.
+
+---
+
+### Top Pitfalls and Prevention Strategies
+
+**v2.2-1 (Critical): Base64 logo bloat in every report**
+Large source images (300-600 KB originals) become 400-800 KB of base64 inlined in every exported
+HTML file, re-allocated on every export call.
+Prevention: Enforce 512 KB max at import time in the settings UI. Store pre-encoded base64 in JSON
+(computed once on import, never re-encoded). Inject the cached string directly into the `
` tag.
+
+**v2.2-2 (Critical): Graph directory listing silently truncates at 999 users**
+`GET /users` returns at most 999 per page. A 5,000-user tenant appears to have 999 users with no
+error and no indication of truncation.
+Prevention: Use `PageIterator` for all full directory fetches. Never
+call `.GetAsync()` on the users collection without following `@odata.nextLink` until null.
+
+**v2.2-3 (Critical): Directory browse exposes guests, service accounts, and disabled accounts by default**
+Raw `GET /users` returns all object types. An MSP tenant with 50+ guest collaborators and service
+accounts produces a noisy, confusing directory.
+Prevention: Default filter `accountEnabled eq true and userType eq 'Member'`. Expose an "Include
+guest accounts" checkbox for explicit opt-in. Apply this filter at the service level, not the
+ViewModel, so the ViewModel is not aware of Graph filter syntax.
+
+**v2.2-4 (Critical): Directory load hangs UI without progress feedback**
+3,000-user tenant takes 3-8 seconds. Without count feedback, the user assumes the feature is
+broken and may double-click the button (triggering concurrent Graph requests).
+Prevention: `DirectoryLoadStatus` observable property updated via `IProgress` in the
+PageIterator callback ("Loading... X users"). Guard `AsyncRelayCommand.CanExecute` during loading.
+Add cancellation button wired to the same `CancellationToken` passed to `PageIterator.IterateAsync`.
+
+**v2.2-5 (Critical): Logo file format validation skipped — broken images in reports**
+OpenFileDialog filter is not sufficient. Renamed non-image files, corrupted JPEGs, and SVG files
+pass the filter but produce broken `
` tags in generated reports.
+Prevention: Validate by loading as `BitmapImage` in a try/catch before persisting. Check
+`PixelWidth` and `PixelHeight` are non-zero. Use `BitmapCacheOption.OnLoad` + retry with
+`IgnoreColorProfile` for EXIF-corrupt JPEGs. Reject SVG explicitly.
+
+**v2.2-6 (Critical): Logo file path stored in JSON becomes stale across machines**
+Storing `C:\Users\admin\logos\msp-logo.png` works on the import machine only. After redistribution
+or reinstall, the path is missing and logos silently disappear from new reports.
+Prevention: Store base64 string directly in `AppSettings` and `TenantProfile` JSON. The original
+file path is discarded after import. The settings file becomes fully portable.
+
+**Moderate pitfalls:**
+- v2.2-7: Logo breaks HTML report print layout — apply `max-height: 60px; max-width: 200px` CSS and add `@media print` rules in the report `