diff --git a/TODO.md b/TODO.md
index 274f915..8c62307 100644
--- a/TODO.md
+++ b/TODO.md
@@ -6,53 +6,6 @@ canonical list of *parked* v1 features is the "Out of scope for v1" section in
---
-## Shared parameter definitions (global and CLI-scoped)
-
-**Problem.** Today every `Snip` carries its own `Parameter` definitions inline.
-If twenty Snips all need an `env` Choice dropdown with options
-`dev` / `staging` / `prod`, that definition is duplicated twenty times and the
-user has to keep them in sync by hand. Same story for any other recurring
-token (`region`, `org_id`, `tenant`, etc.).
-
-**Idea.** Let parameter definitions live above the Snip and be *referenced* by
-name from individual Snips, with the option to still define a parameter
-locally on a Snip when something one-off is needed.
-
-**Sketch.**
-- Add a collection of shared `Parameter` definitions, probably at two scopes:
- - **CLI-scoped** — most common case, e.g. an `env` defined once on the
- `pl-app` CLI and used by every `pl-app` Snip.
- - **Global** — for the rare cross-CLI definition (`yes_no`, common flags).
- - Both scopes should be supported; CLI-scoped takes precedence over global
- when names collide.
-- A Snip can either:
- - **Reference** a shared parameter by name — it picks up the type, options,
- and default automatically.
- - **Define** a parameter locally — overrides any shared definition with the
- same name *for that Snip only*.
-- The substitution engine doesn't change: tokens still resolve from a
- `name → value` dictionary. Only the *definition* moves; resolution is the
- same.
-
-**Open questions** to settle when this gets scheduled:
-- Reference by **name** or by **ID**? Names match the `{token}` model and read
- well; IDs survive renames. Probably name-based with a uniqueness constraint
- per scope, plus a rename flow that propagates.
-- Where does the UI to manage shared parameters live? A Settings page? A
- flyout from each CLI in the pane header? Probably the latter for CLI-scoped
- and a Settings entry for global.
-- Schema migration: additive. New collections on `SnipStoreDocument` (global)
- and `Cli` (CLI-scoped). Existing Snips with local `Parameter` entries keep
- working unchanged.
-- Should a Snip's `Parameters` list contain a discriminated union (local
- definition vs. reference) or two parallel lists? A small object with
- `Name` + optional inline definition feels cleanest — absent inline ⇒ resolve
- from shared scope.
-
-This is the single biggest content-quality-of-life feature after v1 ships.
-
----
-
## Execute Snips, not just construct them (with per-CLI shell + execution history)
**Problem.** Today Snipdeck is a sophisticated clipboard — it builds the command
@@ -297,165 +250,47 @@ 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.
+## Icon picker (glyph browser) for tag icons
----
-
-## Tighten the iteration loop (build/CI feedback)
+**Problem.** Tag icons are set by typing a raw glyph — either pasting a Segoe
+Fluent Icons character or entering its hex code point (`GlyphInput.Resolve`
+already accepts `E8EC`, `U+E8EC`, `0xE8EC`, ``). That works, but it's
+unfriendly: the user has to know or look up a code point and can't see what's
+available. There's no way to browse the icon set.
-**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 main broken (PR #13 was merged with red CI).
-
-**Idea.** Three independent improvements; each is small, all three
-together would make the iteration loop tight.
+**Idea.** A visual icon picker — a searchable grid of glyphs the user clicks to
+choose — instead of (or alongside) typing a code. Driven from the Tags
+management view, and a reusable fit for any future "choose a glyph" need.
**Sketch.**
+- A reusable `IconPicker` control / flyout: a virtualised `GridView` of
+ `FontIcon`s over a list of Segoe Fluent Icons glyphs, with a search box that
+ filters by name and/or code point.
+- Needs a glyph **catalogue** — code point + friendly name — for the grid and
+ search. Either hand-curate a useful subset or embed the published Segoe Fluent
+ Icons mapping; the names are what make search worthwhile.
+- Wire into the Tags view: add a "Choose…" button next to each row that opens
+ the picker, while keeping the free-text field as an escape hatch for pasting /
+ power users.
+- Selection still flows through `GlyphInput.Resolve` and the stored-character
+ model, so persistence is unchanged.
-- **`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 `main` 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 `main` 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.
-
----
+**Open questions** to settle when scheduled:
+- Curated subset vs. full catalogue (the full set is ~1.5k glyphs — needs
+ virtualisation and good search to stay usable).
+- Where do the glyph **names** come from, and is fuzzy search worth it?
+- Do CLI icons (today: uploaded image, identicon fallback) also gain a
+ "pick a glyph instead" option, or stay image-only? Keep the first cut to tags.
-## 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
-load-bearing for the v1 demo, but they're the obvious next-pulls.
-
-- **Hotkey rebinding UI.** The setting is editable in `AppConfig` already;
- what's missing is a key-capture control on the Settings page and the call
- to `IHotkeyService.TryRegister` after the change. Tooling: a small custom
- `Control` that listens for a single key chord then displays it formatted.
-- **Storage path: move / adopt / warn-on-conflict.** Per `CLAUDE.md`, when
- 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.
-- **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.
+## Resizable, size-remembering snip editor
+
+The New/Edit snip editor was widened to fit its content during the UI polish
+pass, but it's still a `ContentDialog` (fixed size). Make it genuinely
+user-resizable and persist the chosen size (to `AppConfig`) so it reopens at
+the same dimensions. `ContentDialog` can't do this natively — the likely route
+is to host the editor in a resizable secondary `Window` (native drag-resize)
+rather than a dialog overlay, which means rethinking how the editor is shown
+and how its result returns through `IShellInteractions`.