diff --git a/TODO.md b/TODO.md
index cf5f66f..40f789a 100644
--- a/TODO.md
+++ b/TODO.md
@@ -297,6 +297,138 @@ Reasons:
---
+## Code-sign the installer (SmartScreen / Authenticode)
+
+**Problem.** The v0.1.0-alpha.1 installer is unsigned. Downloading it in
+Edge / Chrome trips SmartScreen's "this file isn't commonly downloaded —
+make sure you trust it" warning, and running it shows the blue "Windows
+protected your PC" dialog. Every user has to click through "More info →
+Run anyway", which is a terrible first impression and a real deterrent.
+
+**Cause.** SmartScreen reputation is built from a combination of valid
+Authenticode signatures plus aggregate download counts. An unsigned
+binary with zero downloads is automatic prompt-territory. Signing solves
+the warning immediately for EV certs and over time (as downloads
+accumulate) for OV certs.
+
+**Options.**
+
+- **Azure Trusted Signing** (recommended). Microsoft's new managed
+ signing service, ~$10/month, gives you a cloud-hosted signing identity
+ with no HSM to manage. Velopack supports it natively via
+ `--azureTrustedSigningAccount` / `--azureTrustedSigningCertProfile`
+ flags on `vpk pack`. Wants an Azure subscription and an OIDC trust
+ relationship from the GitHub Actions runner — five-step setup, no
+ long-lived secrets in the repo.
+- **Standard OV code-signing certificate.** From DigiCert / Sectigo /
+ GlobalSign, ~$200–400/year. Comes as a cert + key the runner imports.
+ SmartScreen reputation builds gradually rather than instantly. Easier
+ if you already have an account with a CA.
+- **EV code-signing certificate.** ~$400–600/year, requires an HSM /
+ USB token (hard to use from CI without a paid signing service in front
+ of it) but gets immediate SmartScreen reputation. Probably overkill
+ for an alpha; revisit pre-1.0 stable.
+
+**Sketch — Azure Trusted Signing path.**
+
+1. Create the Azure resources (Trusted Signing account, certificate
+ profile, OIDC trust to the GitHub repo) per
+ .
+2. Add the federated-identity secrets / variables to the repo: tenant
+ id, client id, account / profile names.
+3. In `release.yml`, extend the `vpk pack` step with
+ `--azureTrustedSigningAccount`, `--azureTrustedSigningCertProfile`,
+ `--azureTrustedSigningEndpoint` (region URL) and an `azure/login@v2`
+ step ahead of it for federated auth.
+4. Verify with `signtool verify /pa /v Snipdeck-*-Setup.exe` locally
+ after a download, and re-do the manual install smoke test.
+
+**Open questions.**
+
+- Whether the cost ($10/month indefinitely) is acceptable for a hobby /
+ side project. If not, the OV cert path is a single annual payment.
+- Whether the Velopack-generated update packages (the `.nupkg` deltas
+ used by self-update) also need signing for self-update to keep working
+ smoothly under SmartScreen. Worth reading the Velopack signing docs
+ carefully before flipping the switch.
+
+Not urgent — alpha users can click through the prompt — but blocking
+for any kind of broader distribution.
+
+---
+
+## Tighten the iteration loop (build/CI feedback)
+
+**Problem.** During the phase build-out and post-release fixes, the
+build-and-debug cycle relied heavily on PRs as the feedback loop:
+local Linux can't build the `Snipdeck.App` project (the WinUI XAML
+compiler is Windows-only), so analyser errors / build breaks only
+surface in CI. Each round-trip is a PR, which generates churn and
+sometimes ends with master broken (PR #13 was merged with red CI).
+
+**Idea.** Three independent improvements; each is small, all three
+together would make the iteration loop tight.
+
+**Sketch.**
+
+- **`EnableWindowsTargeting=true` for local builds.** Adding this to
+ `Snipdeck.App.csproj` (or passing as `-p:EnableWindowsTargeting=true`
+ on Linux) lets the restore + compile step run on non-Windows hosts.
+ The WinUI XAML pass still requires Windows, but most analyser /
+ C# compiler rules fire under plain `dotnet build` and would catch
+ editorconfig violations (IDE0058, IDE0330, IDE0370, IDE0005 — all
+ hit in this session) before the push.
+- **Branch protection: require status checks to pass.** Add a rule to
+ the existing branch ruleset on `master` that requires the
+ `App build (windows)` and `Core build + tests (ubuntu)` checks to be
+ green before the Merge button activates. Mechanical guardrail
+ against the merged-red scenario.
+- **Draft PRs with force-push fixups during iteration.** Convention,
+ not config: open PRs as **Draft** while iterating, and amend +
+ force-push fixup commits into the original commit instead of stacking
+ "fix lint" follow-ups. The final merged history shows one clean
+ commit per change, which is what the project's commit log wants.
+ Auto-mode currently blocks `git push --force-with-lease` — would
+ need an explicit settings.json permission or a one-off approval
+ to enable. Force-push to `master` itself stays blocked.
+
+**Sequencing.** Do `EnableWindowsTargeting` first (cheapest, biggest
+quality-of-life win for me); then branch protection (one-off setup,
+done forever); then adopt the draft-PR convention.
+
+---
+
+## Final UI polish pass
+
+A deliberate sweep of visual / interaction rough edges, done **at the end**
+once the feature surface has settled — batching the nitpicks avoids
+re-polishing the same screens after every feature lands. Known items so far:
+
+- **Snip card Copy button is too wide.** It currently stretches further than
+ it should; size it to its content (or a sensible fixed width) so the card
+ action row reads cleanly.
+- **"Delete CLI" button should be styled as a danger action.** It's a
+ destructive, hard-to-reverse operation — give it the red/danger accent
+ (e.g. a danger `Button` style / `Foreground` from the theme palette)
+ rather than the neutral default, so it visually distinguishes itself from
+ benign actions.
+- **Inconsistent button corner radii.** Cancel buttons render with square
+ corners while Save / Copy buttons are rounded. Standardise on rounded
+ corners for *all* buttons (the dialog `CloseButton` is the likely culprit —
+ align it with the themed `CornerRadius` the primary buttons pick up).
+- **Consider making the whole Snip card the Copy target.** Rather than a
+ dedicated Copy button on the card, let a click anywhere on the card trigger
+ the copy / parameter-fill flow. Weigh the trade-offs before committing:
+ discoverability and a cleaner card vs. losing an explicit affordance and
+ the risk of accidental copies / conflicts with the overflow menu and
+ favourite star hit-targets. Decide, then either remove the button or keep
+ it.
+
+Add to this list as other cosmetic / interaction snags turn up during
+feature work, then knock them out in one pass before a stable cut.
+
+---
+
## Carried over from the phase stack
These were trimmed out of Phase 4–6 to keep the PRs reviewable. None are
@@ -310,16 +442,20 @@ load-bearing for the v1 demo, but they're the obvious next-pulls.
the user changes the storage path we need three flows: move the existing
store to the new path; adopt a store already at the new path; warn when
both exist. UI: a "Change…" button next to the read-only path display.
-- **Backup retention configurable.** Plumbing: `BackupService` takes
- retention at construction time today; either re-create it on the relevant
- config change or have it read from `AppConfig` lazily.
-- **CLI delete.** Settle cascade semantics — must-be-empty vs trash-all-child-snips —
- before wiring the UI.
-- **Nerdbank.GitVersioning.** Right now `InformationalVersion` falls back to
- the assembly's compile-time version. NBGV would give us a real git-tag-derived
- string at build time (`v1.2.3+gabcdef0`).
-- **Markdown rendering for Snip descriptions.** Stored as plain text right
- now; render via a markdown control on the parameter-fill / detail view.
-- **Trash UI.** Soft-deleted Snips currently just vanish from the views.
- Need a "Trash" entry in the pane footer that lists trashed Snips with a
- restore action and a hard-delete option.
+- **Re-enable `PublishTrimmed` once JSON serialisation is trim-safe.**
+ Disabled in `Snipdeck.App.csproj` to unblock the first release. To
+ turn it back on:
+ 1. Move `JsonSnipStore` / `JsonSettingsStore` onto
+ `JsonSerializerContext` source generation
+ (`[JsonSerializable(typeof(SnipStoreDocument))]` etc.) so the
+ untyped `Serialize/Deserialize` calls disappear. Removes IL2026.
+ 2. Audit Jdenticon-net, Microsoft.Windows.SDK.NET and WinRT.Runtime
+ trim warnings (IL2104); either suppress per-assembly with
+ `` entries / `[DynamicallyAccessedMembers]`
+ attributes, or accept them via targeted
+ `false` carve-outs.
+ 3. Flip `PublishTrimmed` back to `True` for Release.
+
+ Payoff is a meaningfully smaller self-contained Velopack package
+ (probably ~80 MB instead of ~150–200 MB). Not urgent for alpha but
+ worth doing before a stable cut.