diff --git a/src/Agent/AutopilotMonitor.Agent.Core/Monitoring/Collectors/HelloDetector.cs b/src/Agent/AutopilotMonitor.Agent.Core/Monitoring/Collectors/HelloDetector.cs
index 03a0df48..884e14da 100644
--- a/src/Agent/AutopilotMonitor.Agent.Core/Monitoring/Collectors/HelloDetector.cs
+++ b/src/Agent/AutopilotMonitor.Agent.Core/Monitoring/Collectors/HelloDetector.cs
@@ -425,7 +425,7 @@ namespace AutopilotMonitor.Agent.Core.Monitoring.Collectors
case EventId_ProvisioningWillNotLaunch: // 360
eventType = "hello_provisioning_willnotlaunch";
severity = EventSeverity.Warning;
- message = "Windows Hello for Business provisioning prerequisites not met (snapshot only, not a final state";
+ message = "Windows Hello for Business provisioning prerequisites not met (snapshot only, not a final state)";
// DO NOT mark Hello as completed - event 360 is just a snapshot and can change
_logger.Info("Windows Hello provisioning prerequisites not met (snapshot, not terminal)");
break;
diff --git a/src/Agent/AutopilotMonitor.Agent/buildcounter.txt b/src/Agent/AutopilotMonitor.Agent/buildcounter.txt
index 21e72e8a..95f9650f 100644
--- a/src/Agent/AutopilotMonitor.Agent/buildcounter.txt
+++ b/src/Agent/AutopilotMonitor.Agent/buildcounter.txt
@@ -1 +1 @@
-48
+49
diff --git a/src/Web/autopilot-monitor-web/app/globals.css b/src/Web/autopilot-monitor-web/app/globals.css
index dd531536..8870f491 100644
--- a/src/Web/autopilot-monitor-web/app/globals.css
+++ b/src/Web/autopilot-monitor-web/app/globals.css
@@ -4,7 +4,7 @@
html {
scroll-behavior: smooth;
- overflow-y: auto;
+ overflow-y: overlay;
}
:root {
diff --git a/src/Web/autopilot-monitor-web/app/sessions/[sessionId]/page.tsx b/src/Web/autopilot-monitor-web/app/sessions/[sessionId]/page.tsx
index 50678acf..af2bbf82 100644
--- a/src/Web/autopilot-monitor-web/app/sessions/[sessionId]/page.tsx
+++ b/src/Web/autopilot-monitor-web/app/sessions/[sessionId]/page.tsx
@@ -1585,6 +1585,19 @@ function DeviceDetailsCard({ events }: { events: EnrollmentEvent[] }) {
const estimatedBootTime = (bootTime?.bootTimeUtc || bootTime?.bootTime)
? new Date(bootTime?.bootTimeUtc ?? bootTime?.bootTime)
: null;
+
+ // Uptime until enrollment starts: calculated from boot time to first event timestamp.
+ // More accurate than stored uptimeMinutes, which reflects when CollectBootTime() ran (after agent_started).
+ const uptimeUntilEnrollment = useMemo(() => {
+ if (!estimatedBootTime || events.length === 0) return null;
+ const firstEventMs = Math.min(...events.map(e => new Date(e.timestamp).getTime()));
+ const diffMs = firstEventMs - estimatedBootTime.getTime();
+ if (diffMs < 0) return null;
+ const totalMinutes = Math.floor(diffMs / 60000);
+ const hours = Math.floor(totalMinutes / 60);
+ const minutes = totalMinutes % 60;
+ return `${hours}h ${minutes}m`;
+ }, [estimatedBootTime, events]);
const osInfo = getEventData("os_info");
const networkAdapters = getEventData("network_adapters");
const dnsConfig = getEventData("dns_configuration");
@@ -1642,7 +1655,7 @@ function DeviceDetailsCard({ events }: { events: EnrollmentEvent[] }) {
{estimatedBootTime && (
)}
- {bootTime?.uptimeMinutes && }
+ {uptimeUntilEnrollment && }
{agentStarted?.agentVersion && }
{imeVersion && }
{(deviceLocation?.country || deviceLocation?.Country) && (