diff --git a/src/PostIt/PostIt/Services/ContactService.Desktop.cs b/src/PostIt/PostIt/Services/ContactService.Desktop.cs
new file mode 100644
index 00000000..82746c49
--- /dev/null
+++ b/src/PostIt/PostIt/Services/ContactService.Desktop.cs
@@ -0,0 +1,27 @@
+#if !ANDROID && !IOS
+using System;
+using System.Collections.Generic;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace PostIt.Services;
+
+///
+/// Desktop stub for IContactService.
+///
+/// On desktop targets (Linux, macOS, Windows) MAUI Essentials
+/// Contacts.Default throws NotImplementedInReferenceAssemblyException,
+/// so we short-circuit with an empty list rather than trying to
+/// call into the portable facade at runtime.
+///
+/// Future provider plug-ins (Google Contacts API, Exchange EWS,
+/// CardDAV) can either replace this stub on a per-OS basis or
+/// live behind their own IContactService implementation that the
+/// DI container selects by configuration.
+///
+public sealed class ContactService : IContactService
+{
+ public Task> GetDeviceContactsAsync(CancellationToken ct = default)
+ => Task.FromResult>(Array.Empty());
+}
+#endif
diff --git a/src/PostIt/PostIt/Services/ContactService.Mobile.cs b/src/PostIt/PostIt/Services/ContactService.Mobile.cs
new file mode 100644
index 00000000..744fb9a6
--- /dev/null
+++ b/src/PostIt/PostIt/Services/ContactService.Mobile.cs
@@ -0,0 +1,64 @@
+#if ANDROID || IOS
+using System;
+using System.Collections.Generic;
+using System.Threading;
+using System.Threading.Tasks;
+using Microsoft.Maui.ApplicationModel.Communication;
+using Microsoft.Maui.ApplicationModel;
+using Microsoft.Maui.Devices;
+
+namespace PostIt.Services;
+
+///
+/// Mobile implementation backed by MAUI Essentials Contacts.Default.
+///
+/// Compiled only for ANDROID and IOS. On desktop targets, see
+/// ContactService.Desktop.cs (the stub that wins at compile time).
+///
+/// Note: at runtime, this class throws
+/// NotImplementedInReferenceAssemblyException unless the host
+/// application project also references the platform-specific
+/// Microsoft.Maui.Essentials implementation (typically the
+/// PostIt.Android project). On iOS the same is required via
+/// PostIt.iOS. On desktop the stub is used and this file is excluded.
+///
+public sealed class ContactService : IContactService
+{
+ public async Task> GetDeviceContactsAsync(CancellationToken ct = default)
+ {
+ if (DeviceInfo.Current.Platform == DevicePlatform.Unknown)
+ return Array.Empty();
+
+ try
+ {
+ var status = await Permissions.RequestAsync();
+ if (status != PermissionStatus.Granted)
+ return Array.Empty();
+
+ var contacts = await Contacts.Default.GetAllAsync();
+ if (contacts is null) return Array.Empty();
+
+ var result = new List();
+ foreach (var c in contacts)
+ {
+ var emails = new List();
+ if (c.Emails is not null)
+ {
+ foreach (var e in c.Emails)
+ {
+ if (!string.IsNullOrEmpty(e.EmailAddress))
+ emails.Add(e.EmailAddress);
+ }
+ }
+ result.Add(new ContactDto(c.Id, c.DisplayName ?? string.Empty, emails));
+ }
+ return result;
+ }
+ catch (Exception ex)
+ {
+ System.Diagnostics.Debug.WriteLine($"ContactService: {ex.Message}");
+ return Array.Empty();
+ }
+ }
+}
+#endif
diff --git a/src/PostIt/PostIt/Services/ContactService.cs b/src/PostIt/PostIt/Services/ContactService.cs
deleted file mode 100644
index bc71d11b..00000000
--- a/src/PostIt/PostIt/Services/ContactService.cs
+++ /dev/null
@@ -1,39 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Threading.Tasks;
-using Microsoft.Maui.ApplicationModel.Communication;
-using Microsoft.Maui.ApplicationModel;
-using Microsoft.Maui.Devices;
-
-public class ContactService
-{
- public async Task> GetDeviceContactsAsync()
- {
- // 1. Ensure the platform supports MAUI Essentials APIs
- if (DeviceInfo.Current.Platform == DevicePlatform.Unknown)
- {
- throw new PlatformNotSupportedException("MAUI Essentials is not available on this platform.");
- }
-
- try
- {
- // 2. Request runtime permission (Required for Android & iOS)
- var status = await Permissions.RequestAsync();
- if (status != PermissionStatus.Granted)
- {
- // Permission denied by user
- return Array.Empty();
- }
-
- // 3. Fetch all contacts
- var contactsEnumerable = await Contacts.Default.GetAllAsync();
- return contactsEnumerable ?? Array.Empty();
- }
- catch (Exception ex)
- {
- // Handle cross-platform exceptions or logs here
- System.Diagnostics.Debug.WriteLine($"Error fetching contacts: {ex.Message}");
- return Array.Empty();
- }
- }
-}
diff --git a/src/PostIt/PostIt/Services/IContactService.cs b/src/PostIt/PostIt/Services/IContactService.cs
new file mode 100644
index 00000000..8c6da44a
--- /dev/null
+++ b/src/PostIt/PostIt/Services/IContactService.cs
@@ -0,0 +1,29 @@
+using System;
+using System.Collections.Generic;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace PostIt.Services;
+
+///
+/// Abstraction over device contact providers (MAUI Essentials on mobile,
+/// future Google/Exchange/IMAP providers).
+///
+/// Implementations live next to this file in platform-conditional
+/// source files: ContactService.Mobile.cs (ANDROID/IOS) and
+/// ContactService.Desktop.cs (everything else).
+///
+public interface IContactService
+{
+ Task> GetDeviceContactsAsync(CancellationToken ct = default);
+}
+
+///
+/// Platform-neutral contact DTO. Source-of-truth shape for the UI layer;
+/// concrete providers (MAUI Essentials today, Google Contacts API later)
+/// map to this type.
+///
+public sealed record ContactDto(
+ string Id,
+ string DisplayName,
+ IReadOnlyList Emails);