diff --git a/ILSpy.Tests/Updates/UpdatePanelViewModelTests.cs b/ILSpy.Tests/Updates/UpdatePanelViewModelTests.cs
new file mode 100644
index 000000000..5c67da42c
--- /dev/null
+++ b/ILSpy.Tests/Updates/UpdatePanelViewModelTests.cs
@@ -0,0 +1,67 @@
+// Copyright (c) 2026 AlphaSierraPapa for the SharpDevelop Team
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this
+// software and associated documentation files (the "Software"), to deal in the Software
+// without restriction, including without limitation the rights to use, copy, modify, merge,
+// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
+// to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or
+// substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
+// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+using System.Collections.Generic;
+using System.ComponentModel;
+
+using Avalonia.Headless.NUnit;
+
+using AwesomeAssertions;
+
+using ILSpy.AppEnv;
+using ILSpy.ViewModels;
+
+using NUnit.Framework;
+
+namespace ICSharpCode.ILSpy.Tests.Updates;
+
+///
+/// The update banner colours itself by state: green when ILSpy is up to date, amber when an
+/// update is available. is the boolean that
+/// drives that (bound to a style class in the view), so pin that it tracks the download URL.
+///
+[TestFixture]
+public class UpdatePanelViewModelTests
+{
+ [AvaloniaTest]
+ public void UpdateAvailable_tracks_the_download_url()
+ {
+ var vm = AppComposition.Current.GetExport();
+
+ vm.UpdateAvailableDownloadUrl = null;
+ vm.UpdateAvailable.Should().BeFalse("no download URL means ILSpy is up to date");
+
+ vm.UpdateAvailableDownloadUrl = "https://example.invalid/ILSpy.zip";
+ vm.UpdateAvailable.Should().BeTrue("a download URL means an update is available");
+ }
+
+ [AvaloniaTest]
+ public void Setting_the_download_url_notifies_UpdateAvailable()
+ {
+ var vm = AppComposition.Current.GetExport();
+ vm.UpdateAvailableDownloadUrl = null;
+
+ var changed = new List();
+ vm.PropertyChanged += (_, e) => changed.Add(e.PropertyName);
+
+ vm.UpdateAvailableDownloadUrl = "https://example.invalid/ILSpy.zip";
+
+ changed.Should().Contain(nameof(UpdatePanelViewModel.UpdateAvailable),
+ "the banner colour binds to UpdateAvailable, so it must raise PropertyChanged for it");
+ }
+}
diff --git a/ILSpy/ViewModels/UpdatePanelViewModel.cs b/ILSpy/ViewModels/UpdatePanelViewModel.cs
index 167215f67..beebd9dff 100644
--- a/ILSpy/ViewModels/UpdatePanelViewModel.cs
+++ b/ILSpy/ViewModels/UpdatePanelViewModel.cs
@@ -51,6 +51,7 @@ namespace ILSpy.ViewModels
[ObservableProperty]
[NotifyPropertyChangedFor(nameof(ButtonText))]
[NotifyPropertyChangedFor(nameof(Message))]
+ [NotifyPropertyChangedFor(nameof(UpdateAvailable))]
string? updateAvailableDownloadUrl;
[ObservableProperty]
@@ -64,6 +65,10 @@ namespace ILSpy.ViewModels
? "A new version of ILSpy is available."
: "ILSpy is up to date.";
+ /// True once a download URL is known. Drives the banner colour: amber when an
+ /// update is available, green when ILSpy is up to date.
+ public bool UpdateAvailable => UpdateAvailableDownloadUrl != null;
+
[RelayCommand]
void Close() => IsPanelVisible = false;
diff --git a/ILSpy/Views/UpdatePanel.axaml b/ILSpy/Views/UpdatePanel.axaml
index 61005a08f..4ea39a45d 100644
--- a/ILSpy/Views/UpdatePanel.axaml
+++ b/ILSpy/Views/UpdatePanel.axaml
@@ -4,9 +4,25 @@
x:Class="ILSpy.Views.UpdatePanel"
x:DataType="vm:UpdatePanelViewModel"
IsVisible="{Binding IsPanelVisible}">
-
+
+
+
+
+
+
-
+
+