|
| 1 | +# UI/UX Modernization v3 — Fluent Design Foundation |
| 2 | + |
| 3 | +Status: approved 2026-07-30; last reconciled 2026-07-31 (v1.16.0 shipped |
| 4 | +#46–#50 in parallel). Target releases: v1.17–v1.21+. |
| 5 | +Execution order: P0 → P1 → P2 → {P3, P4, P5 parallelizable} → P6 → P7. |
| 6 | +Source: successor to `plans/archive/ui-ux-modernization-v2.md` and |
| 7 | +`plans/archive/2026-07-29-windows-terminal-like-ux.md`. |
| 8 | + |
| 9 | +## Motivation |
| 10 | + |
| 11 | +v1.11–v1.15 closed the *feature* gaps versus Windows Terminal (pill tabs, |
| 12 | +9-category settings GUI with search, profile dropdown, command palette, Quake |
| 13 | +mode). What remains is the *design-language* gap: Nexterm's chrome is drawn |
| 14 | +from ad-hoc constants — flat offset-quad shadows, two competing rounded-rect |
| 15 | +implementations, no shared widget visuals, no hover/press motion, no icon |
| 16 | +system. This plan grounds the visual and interaction language in the official |
| 17 | +Windows 11 design guidance (Fluent Design): |
| 18 | + |
| 19 | +- Design principles (Effortless / Calm / Personal / Familiar / Complete + |
| 20 | + Coherent): <https://learn.microsoft.com/windows/apps/design/design-principles> |
| 21 | +- Signature experiences: geometry, layering & elevation, materials, motion, |
| 22 | + typography, iconography, color |
| 23 | + (<https://learn.microsoft.com/windows/apps/design/signature-experiences/geometry> etc.) |
| 24 | +- App basics: title bar, commanding, dialogs/flyouts, content spacing |
| 25 | + (<https://learn.microsoft.com/windows/apps/design/basics/>) |
| 26 | + |
| 27 | +Strategic differentiator: Windows Terminal is Windows-only by construction. |
| 28 | +Nexterm can carry **one coherent Fluent-informed design language across |
| 29 | +Linux / macOS / Windows** — something WT structurally cannot do. |
| 30 | + |
| 31 | +## Non-goals |
| 32 | + |
| 33 | +- A DOM/web-based UI (`docs/PRODUCT.md` non-goals). Everything below is |
| 34 | + rendered natively with wgpu + cosmic-text. |
| 35 | +- Tab-contains-panes model (ADR-0005: one tab per pane). |
| 36 | +- First-run wizard (still not approved), font presets, OKLCH/wide gamut. |
| 37 | +- Editing the `docs/PRODUCT.md` vision now — revisit with a small follow-up PR |
| 38 | + once P1/P2 have shipped. |
| 39 | + |
| 40 | +## What already exists (do not redo) |
| 41 | + |
| 42 | +- WT-parity UX shipped through v1.15.0 (see the two archived plans above). |
| 43 | +- Color design tokens: `DesignTokens` — 21 color fields derived from |
| 44 | + `SchemePalette` (`nexterm-config/src/schema/tokens.rs`). |
| 45 | +- SDF rounded rectangles: `add_px_rounded_rect_sdf` |
| 46 | + (`nexterm-client-gpu/src/vertex_util.rs:144`) — used by tab pills and the |
| 47 | + settings scrollbar. |
| 48 | +- Animation groundwork: `AnimationManager` (`animations.rs`) with spring + |
| 49 | + eased timers (tab accent, inactive-pane dim, pane fade-in) and the |
| 50 | + `off/subtle/normal/energetic` intensity config. |
| 51 | +- AccessKit tree (`accessibility.rs`); WCAG contrast helper `ensure_readable` |
| 52 | + (settings panel only, `overlay/settings/row.rs:42`). |
| 53 | +- Windows backdrop: `DWMWA_SYSTEMBACKDROP_TYPE = 4` (Mica Alt), applied |
| 54 | + unconditionally (`platform.rs:12`, called from `lifecycle.rs:109`). |
| 55 | +- Shipped 2026-07-30/31 while this plan was in review (parallel plan |
| 56 | + `plans/archive/2026-07-30-wt-titlebar-and-overlay-fix.md`), all released |
| 57 | + as **v1.16.0 (2026-07-31)**: |
| 58 | + - Overlay draw order: the frame renders in two layers (grid, then |
| 59 | + overlays), so grid glyphs no longer bleed through panels (#44). |
| 60 | + - `decorations = "notitle"` implemented as a WT-style custom title bar: |
| 61 | + borderless window, tab bar doubling as the title bar, min/max/close |
| 62 | + buttons exposed to AccessKit, double-click maximize, native system |
| 63 | + menu on Windows. Secondary windows keep native decorations (#46). |
| 64 | + - SDF rounded corners for every overlay panel and chrome corner radius |
| 65 | + default 6 → 10 px; the legacy three-rect helper was removed (#47). |
| 66 | + - In-app system menu for the custom title bar on Linux/macOS (8-locale, |
| 67 | + honours `window.close_action`); Wayland `drag_window` / |
| 68 | + `drag_resize_window` failures are logged instead of swallowed (#48). |
| 69 | + - Windows 11 snap layouts on the custom maximize button: the window proc |
| 70 | + is subclassed to answer `WM_NCHITTEST` with `HTMAXBUTTON` — the P7 |
| 71 | + spike question, answered in production (#49). |
| 72 | + - `window.decorations` now defaults to `"notitle"` on Windows/Linux; |
| 73 | + macOS keeps `"full"` (winit cannot start an interactive resize |
| 74 | + there) (#50). |
| 75 | + |
| 76 | +## Identified gaps |
| 77 | + |
| 78 | +| ID | Gap | Evidence | Impact | |
| 79 | +|-----|-----|----------|--------| |
| 80 | +| G1 | Pipelines blend straight alpha while the surface is `CompositeAlphaMode::PreMultiplied` (Issue #35) — **closed by #45 (2026-07-31)** | `renderer/wgpu_init.rs:172,246,294`; comment at `overlay/settings/mod.rs:98-109` | ★★★ blocks all translucency work | |
| 81 | +| G2 | Two rounded-rect systems; the legacy 3-rect one visibly breaks above 8 px radius — **closed by #47 (2026-07-30)** | `vertex_util.rs:302` vs `:144`; `overlay/util.rs:83-114` | ★★ | |
| 82 | +| G3 | Shadows are flat single-color offset quads; no softness, no elevation scale | `overlay/util.rs:82-94` | ★★★ | |
| 83 | +| G4 | Tokens cover color only; spacing/typography/motion/elevation are ad-hoc constants | `tokens.rs:27-81`; `row.rs:132-135` (`cell_w * 0.6` …) | ★★★ | |
| 84 | +| G5 | No shared widgets: 7 per-tab focus counters; draw / input / AccessKit triple-defined per control | `settings/mod.rs`; `input_handler/mod.rs:590-780`; `accessibility.rs:1590-1824` | ★★★ | |
| 85 | +| G6 | No hover/press/open-close motion; no OS reduced-motion detection | `animations.rs` | ★★ | |
| 86 | +| G7 | Backdrop hard-coded to Mica Alt; `macos_window_background_blur` is dead config; Linux has nothing | `platform.rs:12`; `schema/window.rs:194` | ★★ | |
| 87 | +| G8 | Icons are Unicode glyphs (`▶ Aa ◐`) / opt-in Nerd Font | `settings/category.rs:55-65`; `tab_icons.rs` | ★★ | |
| 88 | +| G9 | No tooltip component anywhere | repo-wide grep | ★★ | |
| 89 | +| G10 | Contrast guard (4.5:1) exists only inside the settings panel | `overlay/settings/row.rs:42` | ★★ | |
| 90 | +| G11 | Hard-coded colors bypass tokens: IME preedit, cursor, OSC 9;4 progress, theme-preview palette duplication | `render_frame.rs:1121,1133`; `vertex_util.rs:389-417`; `ui_verts.rs:1482-1485`; `theme_tab.rs:100-108` | ★ | |
| 91 | + |
| 92 | +## Adopted Fluent reference values |
| 93 | + |
| 94 | +All values verified against Microsoft Learn (see References). |
| 95 | + |
| 96 | +| Domain | Values | |
| 97 | +|---|---| |
| 98 | +| Corner radius | 8 px top-level surfaces (window, dialog, flyout); 4 px in-page controls; 0 px where edges intersect | |
| 99 | +| Spacing ramp | 8 / 12 / 16 / 32 / 48 epx | |
| 100 | +| Type ramp (chrome only, never the terminal grid) | Caption 12/16, Body 14/20, Body Strong 14/20 SB, Subtitle 20/28, Title 28/36 | |
| 101 | +| Motion durations | 83 / 167 / 250 / 333 ms | |
| 102 | +| Motion curves | Direct Entrance `cubic-bezier(0,0,0,1)`; Existing Elements `(0.55,0.55,0,1)`; Gentle Exit `(1,0,1,1)`; Bare Minimum: linear 83 ms opacity | |
| 103 | +| Elevation scale | Dialog 128, Flyout 32, Tooltip 16, Card 8, Control 2 (pressed sinks to 1) | |
| 104 | +| Materials | Mica ≙ long-lived surfaces; Acrylic ≙ transient surfaces (menus, flyouts) | |
| 105 | +| Contrast | ≥ 4.5:1 body text, ≥ 3:1 large text; high-contrast themes target ≥ 7:1 | |
| 106 | + |
| 107 | +## Phases |
| 108 | + |
| 109 | +### P0 — Compositing correctness + SDF unification (S–M) |
| 110 | + |
| 111 | +Fixes G1 (Issue #35) and G2 before anything translucent is built on top. |
| 112 | + |
| 113 | +> **Status 2026-07-31: P0 is complete.** The SDF-unification half (G2) |
| 114 | +> shipped separately in #47; the compositing contract (G1) shipped in #45. |
| 115 | +> The section below is kept as originally scoped for the record. |
| 116 | +
|
| 117 | +**Compositing contract** (the rule every later phase relies on): all fragment |
| 118 | +shaders output **premultiplied alpha**; all pipelines use |
| 119 | +`BlendState::PREMULTIPLIED_ALPHA_BLENDING`; the clear color premultiplies |
| 120 | +`background_opacity` into RGB. Custom `gpu.custom_bg_shader` / |
| 121 | +`custom_text_shader` must premultiply their output — breaking change, called |
| 122 | +out in CHANGELOG and in the config doc comments. |
| 123 | + |
| 124 | +- Touchpoints: `shaders.rs` (3 shaders), `renderer/wgpu_init.rs:172,246,294`, |
| 125 | + `renderer/shader_reload.rs:101,148`, `render_frame.rs` (clear color), |
| 126 | + `nexterm-config/src/schema/gpu.rs` (doc comments). |
| 127 | +- SDF unification: replace the legacy `add_rounded_px_rect` |
| 128 | + (`vertex_util.rs:302`) call sites — starting with `draw_overlay_panel` |
| 129 | + (`overlay/util.rs:83,99,114`) — with `add_px_rounded_rect_sdf`, then delete |
| 130 | + the legacy function. Radius > 8 px now renders correctly (deliberate visual |
| 131 | + improvement). |
| 132 | +- Tests: full suite; any vertex-identity test that asserts the old 3-rect |
| 133 | + output is updated deliberately with rationale in the commit message. |
| 134 | +- Acceptance: with `background_opacity < 1.0` the window composites without |
| 135 | + the washed-out fringe described in #35 (manual check on Windows); no clippy |
| 136 | + warnings; opaque default path visually unchanged. |
| 137 | + |
| 138 | +### P1 — Metric tokens + shared widget layer (XL, 2–3 PRs) |
| 139 | + |
| 140 | +Addresses G4, G5, G9, G11 (principles: Effortless, Familiar, Coherent). |
| 141 | + |
| 142 | +- New `nexterm-config/src/schema/metrics.rs`: `MetricTokens` { spacing ramp, |
| 143 | + radius (control 4 / overlay 8, bridged from the existing |
| 144 | + `UiConfig.corner_radius_*` for backward compatibility), chrome type ramp, |
| 145 | + elevation scale, motion durations + easing table }. Kept separate from the |
| 146 | + palette-derived color `DesignTokens`. |
| 147 | +- New `renderer/overlay/widgets/` module: a `WidgetSpec` descriptor |
| 148 | + (immediate-mode, rebuilt per frame) consumed by exactly three readers — |
| 149 | + `draw_widget` (visuals: real toggle pills, chevrons, sliders, focus ring), |
| 150 | + key/mouse routing via a single `focused_widget_id`, and the AccessKit tree |
| 151 | + builder. This collapses the 7 per-tab focus counters and the triple |
| 152 | + definition of every control. |
| 153 | +- First tooltip component (Tooltip elevation 16, radius 4). |
| 154 | +- Migrate Theme and Window tabs first; remaining tabs follow tab-by-tab with |
| 155 | + old and new coexisting. |
| 156 | +- Migrate G11 hard-coded colors onto tokens; delete the theme-preview |
| 157 | + duplicate palette. |
| 158 | +- Acceptance: every migrated control shares identical hover/press/focus |
| 159 | + visuals; `input_handler` and `accessibility.rs` shrink measurably; a |
| 160 | + tooltip appears on at least the settings sidebar icons. |
| 161 | + |
| 162 | +### P2 — Depth & materials (XL) |
| 163 | + |
| 164 | +Addresses G3, G7 (principles: Calm, Familiar). |
| 165 | + |
| 166 | +- Extend the BG shader with `shadow_softness` and `stroke_width` vertex |
| 167 | + attributes (5 → ~8 attributes; wgpu default max is 16) → soft shadows |
| 168 | + scaled by the elevation table, 1 px focus rings without rect stacking. |
| 169 | +- **In-app acrylic**: render the scene into a persistent offscreen |
| 170 | + `scene_color` texture, run a 4–5 tap Kawase downsample blur chain, and let |
| 171 | + overlay panels sample blur + tint + noise. Captured **once per overlay |
| 172 | + open** and reused (no per-frame recapture → independent of the |
| 173 | + audit-round3 P3 vertex-rebuild debt; no per-frame buffer allocation). |
| 174 | +- New `window.backdrop` config: `auto | mica | mica-alt | acrylic | none`. |
| 175 | + Windows maps to `DWMWA_SYSTEMBACKDROP_TYPE` (turns today's hard-coded |
| 176 | + Mica Alt into a choice); macOS resolves the dead |
| 177 | + `macos_window_background_blur` config (via a vetted crate such as |
| 178 | + `window-vibrancy` or direct objc2 — license/maintenance check first); |
| 179 | + Linux falls back to `none` + the in-app blur. |
| 180 | +- Acceptance: settings panel / palette / dialogs show visibly different |
| 181 | + elevation weights; overlays blur the terminal behind them when |
| 182 | + `backdrop != none`; all three OSes degrade gracefully. |
| 183 | + |
| 184 | +### P3 — Motion language (M–L) |
| 185 | + |
| 186 | +Addresses G6 (principles: Effortless, Calm). |
| 187 | + |
| 188 | +- Add `Timed { start, duration, curve }` animations with the Fluent |
| 189 | + cubic-bezier table to `AnimationManager` (springs stay for interruptible |
| 190 | + motion such as the tab accent). |
| 191 | +- Apply to widget hover/press, dialog/flyout/tooltip open-close (Direct |
| 192 | + Entrance in, Gentle Exit out). |
| 193 | +- OS reduced-motion detection: Windows |
| 194 | + `SystemParametersInfoW(SPI_GETCLIENTAREAANIMATION)`; macOS |
| 195 | + `accessibilityDisplayShouldReduceMotion` (shares the objc2 dependency |
| 196 | + decision with P2); Linux: manual `animations.enabled` config remains the |
| 197 | + fallback. Detection only ever *disables* motion. |
| 198 | +- Acceptance: idle `build_pane_vertices` call count does not regress |
| 199 | + (measured with the tracing counter recommended by |
| 200 | + `plans/audit-round3-2026h2.md` P3); reduced-motion ON renders every |
| 201 | + animation instantly. |
| 202 | + |
| 203 | +### P4 — Iconography & chrome typography (M) |
| 204 | + |
| 205 | +Addresses G8 (principles: Familiar, Personal). |
| 206 | + |
| 207 | +- Bundle a subset of `microsoft/fluentui-system-icons` (MIT — add license |
| 208 | + text to third-party notices) via `include_bytes!` + |
| 209 | + `fontdb::Database::load_font_data`, registered under an explicit family |
| 210 | + name. Nerd Font pipeline stays untouched for terminal-content icons. |
| 211 | +- Replace the settings sidebar Unicode glyphs and menu glyphs; icon sizes |
| 212 | + follow the 16/20/24 px steps. |
| 213 | +- Apply the chrome type ramp (Caption/Body/Subtitle/Title) via |
| 214 | + `FontManager`; the terminal grid keeps the single user-configured font. |
| 215 | +- Acceptance: all chrome icons render without any user-installed font. |
| 216 | + |
| 217 | +### P5 — Accessibility & high contrast (M) |
| 218 | + |
| 219 | +Addresses G10 (principle: Complete + Coherent). |
| 220 | + |
| 221 | +- Move `ensure_readable` out of the settings panel into shared color |
| 222 | + utilities; apply to tab bar, dialogs, palette, blocks UI, status bar. |
| 223 | +- New built-in high-contrast scheme (target ≥ 7:1). |
| 224 | +- Automated contrast tests: every built-in scheme × every token pairing used |
| 225 | + for text must pass 4.5:1. |
| 226 | +- AccessKit roles/status flow from `WidgetSpec` (P1) instead of per-control |
| 227 | + re-definition. |
| 228 | + |
| 229 | +### P6 — Notification surfaces (M) |
| 230 | + |
| 231 | +Principles: Calm, Personal. Fluent surface model: Dialog = blocking |
| 232 | +confirmation of destructive/irreversible actions; Flyout = light-dismiss |
| 233 | +contextual UI; InfoBar = non-blocking status. |
| 234 | + |
| 235 | +- New `overlay/infobar.rs`: non-blocking, auto-dismissing banner (reuses the |
| 236 | + update-banner slot pattern in `ClientState`). |
| 237 | +- Reclassify `ConsentDialog` kinds: keep genuinely destructive/security |
| 238 | + confirmations modal; move low-risk notices to InfoBar. Consent-surface |
| 239 | + changes are security-sensitive — review scope carefully before moving any |
| 240 | + prompt out of a modal. |
| 241 | +- New strings ×8 locales. |
| 242 | + |
| 243 | +### P7 — Full custom title bar (spike S, then XL) |
| 244 | + |
| 245 | +Principle: Familiar (WT-style tabs-in-titlebar silhouette). High risk — |
| 246 | +gated behind a spike. |
| 247 | + |
| 248 | +> **Status 2026-07-31: P7 has effectively shipped ahead of schedule** |
| 249 | +> (v1.16.0). #46 delivered the base `notitle` title bar; #48 the in-app |
| 250 | +> system menu for Linux/macOS; #49 answered the spike question in |
| 251 | +> production (WndProc subclassing + `WM_NCHITTEST`/`HTMAXBUTTON` snap |
| 252 | +> layouts coexist with winit's pump); #50 made `notitle` the |
| 253 | +> Windows/Linux default. The spike gate below is **closed**. Remaining |
| 254 | +> scope is absorbed into earlier phases: Fluent-spec caption-button |
| 255 | +> states/metrics (32 px bar, 5 states) → P1 widget layer + P3 state |
| 256 | +> motion; macOS traffic-light coexistence → revisit with P5; Linux CSD |
| 257 | +> limitations → the P1-adjacent CONFIGURATION.md inventory PR. The |
| 258 | +> section below is kept as originally scoped for the record. |
| 259 | +
|
| 260 | +- **Spike first (go/no-go gate)**: winit 0.30 does not expose |
| 261 | + `WM_NCHITTEST`; snap layouts on Windows 11 require subclassing the window |
| 262 | + proc (`SetWindowLongPtrW(GWLP_WNDPROC)`) and coexisting with winit's |
| 263 | + message pump. Prove hit-testing + snap-layout flyout + no event-loop |
| 264 | + regressions in a throwaway branch before committing to the phase. |
| 265 | +- Implementation after go: `decorations = none` + custom caption buttons |
| 266 | + (min/max/restore/close, 5 visual states, 32 px bar) + drag regions |
| 267 | + (`w.drag_window()` already proven at `mouse.rs:1147`) + double-click |
| 268 | + maximize/restore + right-click system menu; macOS keeps native traffic |
| 269 | + lights over a hidden title bar; Linux documents CSD limitations. |
| 270 | +- Unsafe code needs a safety review; every `unsafe` block carries a |
| 271 | + `// SAFETY:` comment. |
| 272 | + |
| 273 | +## Cross-cutting rules |
| 274 | + |
| 275 | +- Every PR updates `docs/CONFIGURATION.md` for the config fields it touches. |
| 276 | + One inventory PR (S) around P1 backfills the currently undocumented |
| 277 | + fields (`[ui]`, `[animations]`, `[cursor]`, `[quake_mode]`, parts of |
| 278 | + `[window]` / `[tab_bar]`). |
| 279 | +- Every new user-facing string lands in all 8 locales with the key-parity |
| 280 | + test green. |
| 281 | +- `cargo clippy -- -D warnings`, `cargo fmt --check`, full test suite green. |
| 282 | +- GPU output is not CI-verifiable → hand-run screenshots under |
| 283 | + `docs/img/uiux-v3/`. |
| 284 | +- Whenever `Cargo.lock` changes, run |
| 285 | + `bash scripts/regenerate-flatpak-sources.sh` and commit the result. |
| 286 | +- Breaking changes to `custom_bg_shader` / `custom_text_shader` are called |
| 287 | + out in CHANGELOG. |
| 288 | + |
| 289 | +## Risks and mitigations |
| 290 | + |
| 291 | +- **Offscreen rendering is new to this codebase** (P2): resize/DPI handling |
| 292 | + and capture invalidation are the traps. Mitigate with persistent textures, |
| 293 | + capture-once semantics, and a tracing counter on blur-chain executions. |
| 294 | +- **audit-round3 P3 debt** (cursor blink rebuilds pane vertices): P2's |
| 295 | + capture-once design avoids coupling; P3's acceptance criterion guards |
| 296 | + against regression. The debt itself stays tracked in its own plan. |
| 297 | +- **macOS backdrop dependency**: adding `window-vibrancy`/objc2 needs a |
| 298 | + license + maintenance check and a flatpak sources regeneration. |
| 299 | +- **P7 WndProc subclassing**: unsafe, environment-sensitive; proven in |
| 300 | + production by #49 (spike closed 2026-07-31). |
| 301 | +- **Vertex-identity regression tests** will legitimately change in P0/P1; |
| 302 | + update them deliberately, never delete them. |
| 303 | +- **Translation quality** beyond en/ja needs native review eventually |
| 304 | + (existing, not new, debt). |
| 305 | + |
| 306 | +## Release mapping |
| 307 | + |
| 308 | +| Phase | Release | |
| 309 | +|---|---| |
| 310 | +| P0 | v1.17 (v1.16.0 shipped 2026-07-31 carrying #46–#50, before P0 merged) | |
| 311 | +| P1 | v1.17–v1.18 | |
| 312 | +| P2 | v1.18–v1.19 | |
| 313 | +| P3 | v1.19 | |
| 314 | +| P4 | v1.19–v1.20 | |
| 315 | +| P5 | v1.20 | |
| 316 | +| P6 | v1.21 | |
| 317 | +| P7 | mostly shipped in v1.16.0 (#46/#48/#49/#50); remainder folds into P1/P3/P5 | |
| 318 | + |
| 319 | +## Progress |
| 320 | + |
| 321 | +- [x] P0 (SDF half) rounded-rect unification — shipped via #47 (2026-07-30) |
| 322 | +- [x] P0 (compositing half) premultiplied-alpha contract — shipped via #45 |
| 323 | + (2026-07-31; on-device visual checks listed in the PR remain pending) |
| 324 | +- [ ] P1a metric tokens (`metrics.rs`) |
| 325 | +- [ ] P1b widget layer + Theme/Window tab migration + tooltip |
| 326 | +- [ ] P1c remaining tabs + hard-coded color migration |
| 327 | +- [ ] CONFIGURATION.md inventory PR |
| 328 | +- [ ] P2a soft shadows + stroke (shader attributes) |
| 329 | +- [ ] P2b in-app acrylic (offscreen + Kawase blur) |
| 330 | +- [ ] P2c `window.backdrop` config (Win/macOS/Linux) |
| 331 | +- [ ] P3 motion language + reduced-motion detection |
| 332 | +- [ ] P4 icon font + chrome type ramp |
| 333 | +- [ ] P5 contrast everywhere + high-contrast scheme |
| 334 | +- [ ] P6 InfoBar + consent reclassification |
| 335 | +- [x] P7 base `notitle` custom title bar — shipped early via #46 (2026-07-30) |
| 336 | +- [x] P7 spike: Windows 11 snap layouts — answered in production via #49 (2026-07-31) |
| 337 | +- [x] P7 default-on decision — `notitle` default on Windows/Linux via #50 (2026-07-31) |
| 338 | +- [ ] P7 remainder — absorbed into P1 (button widget), P3 (state motion), P5 (macOS coexistence) |
| 339 | + |
| 340 | +## References |
| 341 | + |
| 342 | +- Design principles: <https://learn.microsoft.com/windows/apps/design/design-principles> |
| 343 | +- Guidelines overview: <https://learn.microsoft.com/windows/apps/design/guidelines-overview> |
| 344 | +- Geometry: <https://learn.microsoft.com/windows/apps/design/signature-experiences/geometry> |
| 345 | +- Layering & elevation: <https://learn.microsoft.com/windows/apps/design/signature-experiences/layering> |
| 346 | +- Materials: <https://learn.microsoft.com/windows/apps/design/style/mica>, |
| 347 | + <https://learn.microsoft.com/windows/apps/design/style/acrylic> |
| 348 | +- Motion: <https://learn.microsoft.com/windows/apps/design/signature-experiences/motion>, |
| 349 | + <https://learn.microsoft.com/windows/apps/design/motion/timing-and-easing> |
| 350 | +- Typography: <https://learn.microsoft.com/windows/apps/design/signature-experiences/typography> |
| 351 | +- Iconography: <https://learn.microsoft.com/windows/apps/design/iconography/segoe-fluent-icons-font> |
| 352 | + (values only; the font itself is not redistributable — bundled icons come |
| 353 | + from MIT-licensed `microsoft/fluentui-system-icons`) |
| 354 | +- Title bar: <https://learn.microsoft.com/windows/apps/design/basics/titlebar-design> |
| 355 | +- Commanding / dialogs: <https://learn.microsoft.com/windows/apps/design/basics/commanding-basics> |
| 356 | +- Content spacing: <https://learn.microsoft.com/windows/apps/design/basics/content-basics> |
| 357 | +- Accessibility: <https://learn.microsoft.com/windows/apps/design/accessibility/accessible-text-requirements> |
0 commit comments