diff --git a/ZeroSpace/ZeroSpace.MapEditor/Views/MapDrawable.cs b/ZeroSpace/ZeroSpace.MapEditor/Views/MapDrawable.cs
new file mode 100644
index 0000000..e4223e9
--- /dev/null
+++ b/ZeroSpace/ZeroSpace.MapEditor/Views/MapDrawable.cs
@@ -0,0 +1,77 @@
+using Microsoft.Maui.Graphics;
+using ZeroSpace.MapEditor.Models;
+
+namespace ZeroSpace.MapEditor.Views;
+
+///
+/// Draws the star map: connection lines between connected systems and
+/// one circle per system. Names are intentionally not drawn on the
+/// canvas; details live in the inspector.
+///
+public sealed class MapDrawable : IDrawable
+{
+ public const double NodeRadius = 14;
+
+ public IList Nodes { get; set; } = Array.Empty();
+
+ public Func FindNode { get; set; } = _ => null;
+
+ /// Screen pixels per world unit.
+ public double Scale { get; set; } = 1;
+
+ public double OffsetX { get; set; }
+
+ public double OffsetY { get; set; }
+
+ public void Draw(ICanvas canvas, RectF dirtyRect)
+ {
+ canvas.FillColor = Color.FromArgb("#1e2430");
+ canvas.FillRectangle(dirtyRect);
+
+ PointF ToScreen(double worldX, double worldY) =>
+ new((float)(worldX * Scale + OffsetX), (float)(worldY * Scale + OffsetY));
+
+ // Connections first, so nodes draw on top of the lines.
+ canvas.StrokeColor = Color.FromArgb("#5b6b82");
+ canvas.StrokeSize = Math.Max(1, (float)(1.5 * Scale));
+ foreach (var node in Nodes)
+ {
+ var from = ToScreen(node.X, node.Y);
+ foreach (var name in node.Doc.ConnectedSystems)
+ {
+ var target = FindNode(name);
+ if (target is null || ReferenceEquals(target, node))
+ {
+ continue;
+ }
+
+ var to = ToScreen(target.X, target.Y);
+ canvas.DrawLine(from, to);
+ }
+ }
+
+ foreach (var node in Nodes)
+ {
+ var center = ToScreen(node.X, node.Y);
+ var radius = (float)(NodeRadius * Scale);
+
+ canvas.FillColor = ColorForKind(node.Doc.Kind);
+ canvas.FillCircle(center, radius);
+
+ if (node.IsSelected)
+ {
+ canvas.StrokeColor = Colors.White;
+ canvas.StrokeSize = 3;
+ canvas.DrawCircle(center, radius + 6);
+ }
+ }
+ }
+
+ public static Color ColorForKind(string kind) => kind switch
+ {
+ "Homeworld" => Color.FromArgb("#43a047"),
+ "Core" => Color.FromArgb("#fb8c00"),
+ "Side" => Color.FromArgb("#4a90d9"),
+ _ => Color.FromArgb("#9aa5b1"),
+ };
+}