diff --git a/Content.Client/Access/UI/AgentIDCardWindow.xaml b/Content.Client/Access/UI/AgentIDCardWindow.xaml
index 4947cd7f10286f..89de793714d615 100644
--- a/Content.Client/Access/UI/AgentIDCardWindow.xaml
+++ b/Content.Client/Access/UI/AgentIDCardWindow.xaml
@@ -6,7 +6,7 @@
-
+
diff --git a/Content.Client/Administration/UI/BanPanel/BanPanel.xaml b/Content.Client/Administration/UI/BanPanel/BanPanel.xaml
index 64eb7d206cf83f..b8f91e050ea1f4 100644
--- a/Content.Client/Administration/UI/BanPanel/BanPanel.xaml
+++ b/Content.Client/Administration/UI/BanPanel/BanPanel.xaml
@@ -12,7 +12,7 @@
-
+
diff --git a/Content.Client/Gateway/UI/GatewayBoundUserInterface.cs b/Content.Client/Gateway/UI/GatewayBoundUserInterface.cs
new file mode 100644
index 00000000000000..9478f0ab452579
--- /dev/null
+++ b/Content.Client/Gateway/UI/GatewayBoundUserInterface.cs
@@ -0,0 +1,45 @@
+using Content.Shared.Gateway;
+using JetBrains.Annotations;
+using Robust.Client.GameObjects;
+
+namespace Content.Client.Gateway.UI;
+
+[UsedImplicitly]
+public sealed class GatewayBoundUserInterface : BoundUserInterface
+{
+ private GatewayWindow? _window;
+
+ public GatewayBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey)
+ {
+ }
+
+ protected override void Open()
+ {
+ base.Open();
+
+ _window = new GatewayWindow();
+ _window.OpenPortal += destination =>
+ {
+ SendMessage(new GatewayOpenPortalMessage(destination));
+ };
+ _window.OnClose += Close;
+ _window?.OpenCentered();
+ }
+
+ protected override void Dispose(bool disposing)
+ {
+ base.Dispose(disposing);
+ _window?.Dispose();
+ _window = null;
+ }
+
+ protected override void UpdateState(BoundUserInterfaceState state)
+ {
+ base.UpdateState(state);
+
+ if (state is not GatewayBoundUserInterfaceState current)
+ return;
+
+ _window?.UpdateState(current);
+ }
+}
diff --git a/Content.Client/Gateway/UI/GatewayWindow.xaml b/Content.Client/Gateway/UI/GatewayWindow.xaml
new file mode 100644
index 00000000000000..49e6bb679b6fcb
--- /dev/null
+++ b/Content.Client/Gateway/UI/GatewayWindow.xaml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Content.Client/Gateway/UI/GatewayWindow.xaml.cs b/Content.Client/Gateway/UI/GatewayWindow.xaml.cs
new file mode 100644
index 00000000000000..b070cf3176eddc
--- /dev/null
+++ b/Content.Client/Gateway/UI/GatewayWindow.xaml.cs
@@ -0,0 +1,180 @@
+using Content.Client.Computer;
+using Content.Client.Stylesheets;
+using Content.Client.UserInterface.Controls;
+using Content.Shared.Gateway;
+using Content.Shared.Shuttles.BUIStates;
+using Robust.Client.AutoGenerated;
+using Robust.Client.Graphics;
+using Robust.Client.UserInterface;
+using Robust.Client.UserInterface.Controls;
+using Robust.Client.UserInterface.XAML;
+using Robust.Shared.Timing;
+
+namespace Content.Client.Gateway.UI;
+
+[GenerateTypedNameReferences]
+public sealed partial class GatewayWindow : FancyWindow,
+ IComputerWindow
+{
+ private readonly IGameTiming _timing;
+
+ public event Action? OpenPortal;
+ private List<(EntityUid, string, TimeSpan, bool)> _destinations = default!;
+ private EntityUid? _current;
+ private TimeSpan _nextClose;
+ private TimeSpan _lastOpen;
+ private List