diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index 8f4cbff..e2ae504 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -637,10 +637,10 @@ jobs:
dotnet publish LanMountainDesktop/LanMountainDesktop.csproj \
-c Release \
-o ./publish/macos-${{ matrix.arch }}-app \
- --self-contained \
+ --self-contained:false \
-r osx-${{ matrix.arch }} \
+ -p:SelfContained=false \
-p:PublishSingleFile=false \
- -p:SelfContained=true \
-p:DebugType=none \
-p:DebugSymbols=false \
-p:SkipAirAppHostBuild=true \
@@ -651,6 +651,17 @@ jobs:
-p:FileVersion=${{ needs.prepare.outputs.assembly_version }} \
-p:InformationalVersion=${{ needs.prepare.outputs.informational_version }}
+ - name: Optimize and Guard macOS Payload
+ run: |
+ arch="${{ matrix.arch }}"
+ publishDir="publish/macos-${arch}-app"
+
+ pwsh ./LanMountainDesktop/scripts/Optimize-PublishPayload.ps1 \
+ -PublishDir "$publishDir" \
+ -RuntimeIdentifier "osx-${arch}" \
+ -AssertClean
+ shell: bash
+
- name: Package Payload Zip
run: |
release_dir="$PWD/release-assets"
diff --git a/.trae/specs/settings-window-fluent-shell-redesign/spec.md b/.trae/specs/settings-window-fluent-shell-redesign/spec.md
index 709207d..b1d941e 100644
--- a/.trae/specs/settings-window-fluent-shell-redesign/spec.md
+++ b/.trae/specs/settings-window-fluent-shell-redesign/spec.md
@@ -8,7 +8,10 @@ Rebuild the settings window as an independent Fluent shell with a custom titleba
- Keep the existing independent settings-window lifecycle: open-or-focus, no owner anchor, own taskbar entry.
- Use a 48 DIP titlebar with Back, pane toggle, icon/title, search, restart action, more menu, and caption-button spacer.
+- Keep the titlebar and content area on one shared full-window background layer; the custom titlebar must remain transparent and must not paint a contrasting strip.
+- Avoid a visible titlebar bottom divider that makes the titlebar read as a separate color band.
- Keep `FANavigationView` as the primary navigation surface with `OpenPaneLength` around 283 DIP.
+- Keep `FANavigationView` pane and content template backgrounds transparent in the settings shell so the navigation control does not reintroduce a second surface color.
- Move the compact/minimal pane toggle from the navigation footer into the titlebar.
- Add search over built-in settings pages and settings expanders; selecting a result navigates, expands, focuses, and highlights.
- Add `auto` system material mode and make it the default.
diff --git a/LanMountainDesktop.Tests/SettingsWindowShellVisualTests.cs b/LanMountainDesktop.Tests/SettingsWindowShellVisualTests.cs
new file mode 100644
index 0000000..510e386
--- /dev/null
+++ b/LanMountainDesktop.Tests/SettingsWindowShellVisualTests.cs
@@ -0,0 +1,93 @@
+using Xunit;
+
+namespace LanMountainDesktop.Tests;
+
+public sealed class SettingsWindowShellVisualTests
+{
+ [Fact]
+ public void SettingsWindow_UsesOneFullWindowBackgroundBehindTitlebarAndContent()
+ {
+ var xaml = ReadRepositoryFile("LanMountainDesktop", "Views", "SettingsWindow.axaml");
+
+ Assert.Contains("x:Name=\"RootGrid\"", xaml);
+ Assert.Contains("Background=\"Transparent\"", ExtractElementStart(xaml, "", xaml);
+ Assert.Contains("", xaml);
+ Assert.Contains("", xaml);
+ Assert.Contains("", xaml);
+ Assert.Contains("", xaml);
+ }
+
+ [Fact]
+ public void NavigationStyles_KeepSettingsNavigationTemplateTransparent()
+ {
+ var styles = ReadRepositoryFile("LanMountainDesktop", "Styles", "NavigationStyles.axaml");
+
+ Assert.Contains("ui|FANavigationView.settings-navigation-view", styles);
+ Assert.Contains("Grid#RootGrid", styles);
+ Assert.Contains("Grid#ContentGrid", styles);
+ Assert.Contains("Grid#PaneRoot", styles);
+ Assert.Contains("Border#NavigationViewBorder", styles);
+ Assert.Contains("Border#ContentGridBorder", styles);
+ Assert.Contains("Border#PaneBorder", styles);
+ Assert.Contains("", styles);
+ Assert.Contains("", styles);
+ }
+
+ private static string ExtractElementStart(string source, string startToken)
+ {
+ var start = source.IndexOf(startToken, StringComparison.Ordinal);
+ Assert.True(start >= 0, $"Could not find '{startToken}'.");
+
+ var end = source.IndexOf('>', start);
+ Assert.True(end > start, $"Could not find end of '{startToken}'.");
+
+ return source.Substring(start, end - start + 1);
+ }
+
+ private static string ReadRepositoryFile(params string[] segments)
+ {
+ var directory = new DirectoryInfo(AppContext.BaseDirectory);
+ while (directory is not null)
+ {
+ var candidate = Path.Combine(new[] { directory.FullName }.Concat(segments).ToArray());
+ if (File.Exists(candidate))
+ {
+ return File.ReadAllText(candidate);
+ }
+
+ if (File.Exists(Path.Combine(directory.FullName, "LanMountainDesktop.slnx")))
+ {
+ break;
+ }
+
+ directory = directory.Parent;
+ }
+
+ throw new FileNotFoundException($"Could not locate repository file '{Path.Combine(segments)}'.");
+ }
+}
diff --git a/LanMountainDesktop/Styles/NavigationStyles.axaml b/LanMountainDesktop/Styles/NavigationStyles.axaml
index 67425e4..721bcc0 100644
--- a/LanMountainDesktop/Styles/NavigationStyles.axaml
+++ b/LanMountainDesktop/Styles/NavigationStyles.axaml
@@ -116,6 +116,7 @@
+
+
+
+