diff --git a/Horizon/App.xaml b/Horizon/App.xaml
index 574fc12..d7a09ee 100644
--- a/Horizon/App.xaml
+++ b/Horizon/App.xaml
@@ -1,7 +1,14 @@
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Horizon/Horizon.csproj b/Horizon/Horizon.csproj
index 798c5cb..7f09dc9 100644
--- a/Horizon/Horizon.csproj
+++ b/Horizon/Horizon.csproj
@@ -11,6 +11,7 @@
alpha
false
Horizon.ico
+ true
diff --git a/Horizon/Resources/UI/Animations.xaml b/Horizon/Resources/UI/Animations.xaml
new file mode 100644
index 0000000..c066f10
--- /dev/null
+++ b/Horizon/Resources/UI/Animations.xaml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/Horizon/Resources/UI/Brushes.xaml b/Horizon/Resources/UI/Brushes.xaml
new file mode 100644
index 0000000..d9ec3fa
--- /dev/null
+++ b/Horizon/Resources/UI/Brushes.xaml
@@ -0,0 +1,25 @@
+
+
+ #2A2A2D
+ #000000
+ #FFFFFF
+ #990000
+ #770000
+ #7AC1FF
+ #4A4A4D
+ #8A8A8D
+ #C95100
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Horizon/Resources/UI/ControlDefinitions/WindowDefinition.xaml b/Horizon/Resources/UI/ControlDefinitions/WindowDefinition.xaml
new file mode 100644
index 0000000..46d2ba1
--- /dev/null
+++ b/Horizon/Resources/UI/ControlDefinitions/WindowDefinition.xaml
@@ -0,0 +1,94 @@
+
+
+
\ No newline at end of file
diff --git a/Horizon/Resources/UI/Controls.xaml b/Horizon/Resources/UI/Controls.xaml
new file mode 100644
index 0000000..998643d
--- /dev/null
+++ b/Horizon/Resources/UI/Controls.xaml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Horizon/Resources/UI/Converters.xaml b/Horizon/Resources/UI/Converters.xaml
new file mode 100644
index 0000000..42f1cd1
--- /dev/null
+++ b/Horizon/Resources/UI/Converters.xaml
@@ -0,0 +1,3 @@
+
+
\ No newline at end of file
diff --git a/Horizon/Utilities/KeyConstants.cs b/Horizon/Utilities/KeyConstants.cs
new file mode 100644
index 0000000..56aefa3
--- /dev/null
+++ b/Horizon/Utilities/KeyConstants.cs
@@ -0,0 +1,138 @@
+using System.Windows.Input;
+
+namespace Horizon.Utilities;
+
+///
+/// Contains constants for handling key codes.
+///
+public static class KeyConstants
+{
+ ///
+ /// Contains a list of keys that should be rendered as medium size.
+ ///
+ public static List MediumSizeKeys { get; } =
+ [
+ Key.Tab,
+ Key.CapsLock,
+ Key.LeftShift,
+ Key.RightShift,
+ Key.LeftAlt,
+ Key.RightAlt,
+ Key.LeftCtrl,
+ Key.RightCtrl,
+ Key.Back,
+ Key.Apps,
+ Key.Enter,
+ Key.Add,
+ Key.Insert
+ ];
+
+ ///
+ /// Contains the friendly names for each defined key on the keyboard.
+ ///
+ public static Dictionary KeyNames { get; } = new()
+ {
+ [Key.Escape] = "Esc",
+ [Key.F1] = "F1",
+ [Key.F2] = "F2",
+ [Key.F3] = "F3",
+ [Key.F4] = "F4",
+ [Key.F5] = "F5",
+ [Key.F6] = "F6",
+ [Key.F7] = "F7",
+ [Key.F8] = "F8",
+ [Key.F9] = "F9",
+ [Key.F10] = "F10",
+ [Key.F11] = "F11",
+ [Key.F12] = "F12",
+ [Key.PrintScreen] = "Print Sc",
+ [Key.Scroll] = "Scroll Lock",
+ [Key.Pause] = "Pause",
+ [Key.Oem3] = "`",
+ [Key.D1] = "1",
+ [Key.D2] = "2",
+ [Key.D3] = "3",
+ [Key.D4] = "4",
+ [Key.D5] = "5",
+ [Key.D6] = "6",
+ [Key.D7] = "7",
+ [Key.D8] = "8",
+ [Key.D9] = "9",
+ [Key.D0] = "0",
+ [Key.OemMinus] = "-",
+ [Key.OemPlus] = "+",
+ [Key.Back] = "Backspace",
+ [Key.Tab] = "Tab",
+ [Key.Q] = "Q",
+ [Key.W] = "W",
+ [Key.E] = "E",
+ [Key.R] = "R",
+ [Key.T] = "T",
+ [Key.Y] = "Y",
+ [Key.U] = "U",
+ [Key.I] = "I",
+ [Key.O] = "O",
+ [Key.P] = "P",
+ [Key.Oem4] = "[",
+ [Key.Oem6] = "]",
+ [Key.Oem5] = "\\",
+ [Key.CapsLock] = "Caps Lock",
+ [Key.A] = "A",
+ [Key.S] = "S",
+ [Key.D] = "D",
+ [Key.F] = "F",
+ [Key.G] = "G",
+ [Key.H] = "H",
+ [Key.J] = "J",
+ [Key.K] = "K",
+ [Key.L] = "L",
+ [Key.Oem1] = ";",
+ [Key.Oem7] = "'",
+ [Key.Enter] = "Enter",
+ [Key.LeftShift] = "Shift",
+ [Key.Z] = "Z",
+ [Key.X] = "X",
+ [Key.C] = "C",
+ [Key.V] = "V",
+ [Key.B] = "B",
+ [Key.N] = "N",
+ [Key.M] = "M",
+ [Key.OemComma] = ",",
+ [Key.OemPeriod] = ".",
+ [Key.Oem2] = "/",
+ [Key.RightShift] = "Shift",
+ [Key.LeftCtrl] = "Ctrl",
+ [Key.LWin] = "Win",
+ [Key.LeftAlt] = "Alt",
+ [Key.Space] = "Space",
+ [Key.RightAlt] = "Alt",
+ [Key.Apps] = "≣",
+ [Key.RightCtrl] = "Ctrl",
+ [Key.Insert] = "Insert",
+ [Key.Home] = "Home",
+ [Key.PageUp] = "Pg Up",
+ [Key.Delete] = "Delete",
+ [Key.End] = "End",
+ [Key.PageDown] = "Pg Dn",
+ [Key.Up] = "↑",
+ [Key.Down] = "↓",
+ [Key.Left] = "←",
+ [Key.Right] = "→",
+ [Key.NumLock] = "Num Lock",
+ [Key.Divide] = "Numpad /",
+ [Key.Multiply] = "Numpad *",
+ [Key.Subtract] = "Numpad -",
+ [Key.Add] = "Numpad +",
+ [Key.Decimal] = "Numpad .",
+ [Key.NumPad1] = "N1",
+ [Key.NumPad2] = "N2",
+ [Key.NumPad3] = "N3",
+ [Key.NumPad4] = "N4",
+ [Key.NumPad5] = "N5",
+ [Key.NumPad6] = "N6",
+ [Key.NumPad7] = "N7",
+ [Key.NumPad8] = "N8",
+ [Key.NumPad9] = "N9",
+ [Key.NumPad0] = "N0"
+ };
+}
\ No newline at end of file
diff --git a/Horizon/Utilities/NativeUtilities.cs b/Horizon/Utilities/NativeUtilities.cs
new file mode 100644
index 0000000..546f747
--- /dev/null
+++ b/Horizon/Utilities/NativeUtilities.cs
@@ -0,0 +1,32 @@
+using System.Runtime.InteropServices;
+
+namespace Horizon.Utilities;
+
+///
+/// Magic native methods used for windows and popups.
+///
+internal static partial class NativeUtilities
+{
+ internal static uint TPM_LEFTALIGN;
+
+ internal static uint TPM_RETURNCMD;
+
+ static NativeUtilities()
+ {
+ TPM_LEFTALIGN = 0;
+ TPM_RETURNCMD = 256;
+ }
+
+ [LibraryImport("user32.dll")]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ internal static partial bool EnableMenuItem(IntPtr hMenu, uint uIDEnableItem, uint uEnable);
+
+ [LibraryImport("user32.dll", SetLastError = true)]
+ internal static partial IntPtr GetSystemMenu(IntPtr hWnd, [MarshalAs(UnmanagedType.Bool)] bool bRevert);
+
+ [LibraryImport("user32.dll")]
+ internal static partial IntPtr PostMessage(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam);
+
+ [LibraryImport("user32.dll")]
+ internal static partial int TrackPopupMenuEx(IntPtr hmenu, uint fuFlags, int x, int y, IntPtr hwnd, IntPtr lptpm);
+}
\ No newline at end of file
diff --git a/Horizon/Utilities/RECT.cs b/Horizon/Utilities/RECT.cs
new file mode 100644
index 0000000..93056f4
--- /dev/null
+++ b/Horizon/Utilities/RECT.cs
@@ -0,0 +1,60 @@
+using System.Windows;
+
+namespace Horizon.Utilities;
+
+///
+/// A custom rect struct used only for native utilities.
+///
+[Serializable]
+internal struct RECT
+{
+ public int Bottom;
+
+ public int Left;
+
+ public int Right;
+
+ public int Top;
+
+ public RECT(int left, int top, int right, int bottom)
+ {
+ this.Left = left;
+ this.Top = top;
+ this.Right = right;
+ this.Bottom = bottom;
+ }
+
+ public RECT(Rect rect)
+ {
+ this.Left = (int)rect.Left;
+ this.Top = (int)rect.Top;
+ this.Right = (int)rect.Right;
+ this.Bottom = (int)rect.Bottom;
+ }
+
+ public int Height
+ {
+ readonly get => this.Bottom - this.Top;
+ set => this.Bottom = this.Top + value;
+ }
+
+ public readonly Point Position => new(this.Left, this.Top);
+
+ public readonly Size Size => new(this.Width, this.Height);
+
+ public int Width
+ {
+ readonly get => this.Right - this.Left;
+ set => this.Right = this.Left + value;
+ }
+
+ public void Offset(int dx, int dy)
+ {
+ this.Left += dx;
+ this.Right += dx;
+ this.Top += dy;
+ this.Bottom += dy;
+ }
+
+ public readonly Int32Rect ToInt32Rect() => new(this.Left, this.Top, this.Width, this.Height);
+}
\ No newline at end of file
diff --git a/Horizon/Utilities/SystemHelper.cs b/Horizon/Utilities/SystemHelper.cs
new file mode 100644
index 0000000..9bf15fd
--- /dev/null
+++ b/Horizon/Utilities/SystemHelper.cs
@@ -0,0 +1,29 @@
+using System.Reflection;
+using System.Windows;
+using System.Windows.Forms;
+
+namespace Horizon.Utilities;
+
+///
+/// A helper used for low-level windows system methods such as getting DPI and mouse position.
+///
+internal static class SystemHelper
+{
+ ///
+ /// Gets the current system DPI.
+ ///
+ /// The DPI as an .
+ public static int GetCurrentDPI() => ((int?)typeof(SystemParameters).GetProperty("Dpi", BindingFlags.Static | BindingFlags.NonPublic)?.GetValue(null, null)) ?? 0;
+
+ ///
+ /// Gets the current system DPI scale factor.
+ ///
+ /// The scale factor as a .
+ public static double GetCurrentDPIScaleFactor() => (double)GetCurrentDPI() / 96;
+
+ ///
+ /// Gets the mouse position as defined in Windows Forms.
+ ///
+ /// A representing the mouse position.
+ public static Point GetMousePositionWindowsForms() => new(Control.MousePosition.X, Control.MousePosition.Y);
+}
\ No newline at end of file
diff --git a/Horizon/View/Windows/BorderlessReactiveWindow.cs b/Horizon/View/Windows/BorderlessReactiveWindow.cs
new file mode 100644
index 0000000..d99cfe0
--- /dev/null
+++ b/Horizon/View/Windows/BorderlessReactiveWindow.cs
@@ -0,0 +1,68 @@
+using ReactiveUI;
+using System.Windows;
+
+namespace Horizon.View.Windows;
+
+///
+/// A that is reactive.
+///
+///
+///
+/// This class is a that is also reactive. That is, it implements . You can
+/// extend this class to get an implementation of rather than writing one yourself.
+///
+///
+/// Note that the XAML for your control must specify the same base class, including the generic argument you provide for your
+/// view model. To do this, use the TypeArguments attribute as follows:
+///
+///
+///
+///
+///]]>
+///
+///
+///
+/// The type of the view model backing the view.
+public abstract class BorderlessReactiveWindow :
+ BorderlessWindow, IViewFor
+ where TViewModel : class
+{
+ ///
+ /// The view model dependency property.
+ ///
+ public static readonly DependencyProperty ViewModelProperty =
+ DependencyProperty.Register(
+ "ViewModel",
+ typeof(TViewModel),
+ typeof(BorderlessReactiveWindow),
+ new PropertyMetadata(null));
+
+ ///
+ /// Gets the binding root view model.
+ ///
+ public TViewModel? BindingRoot => this.ViewModel;
+
+ ///
+ public TViewModel? ViewModel
+ {
+ get => (TViewModel?)this.GetValue(ViewModelProperty);
+ set => this.SetValue(ViewModelProperty, value);
+ }
+
+ ///
+ object? IViewFor.ViewModel
+ {
+ get => this.ViewModel;
+ set => this.ViewModel = (TViewModel?)value;
+ }
+}
\ No newline at end of file
diff --git a/Horizon/View/Windows/BorderlessWindow.cs b/Horizon/View/Windows/BorderlessWindow.cs
new file mode 100644
index 0000000..8377fdd
--- /dev/null
+++ b/Horizon/View/Windows/BorderlessWindow.cs
@@ -0,0 +1,404 @@
+using Horizon.Utilities;
+using JetBrains.Annotations;
+using Microsoft.Win32;
+using System.Diagnostics;
+using System.Drawing;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Forms;
+using System.Windows.Input;
+using System.Windows.Interop;
+using Button = System.Windows.Controls.Button;
+using MouseEventArgs = System.Windows.Input.MouseEventArgs;
+using MouseEventHandler = System.Windows.Input.MouseEventHandler;
+using Point = System.Windows.Point;
+
+namespace Horizon.View.Windows;
+
+public class BorderlessWindow : Window
+{
+#pragma warning disable IDE0052 // Remove unread private members
+ [UsedImplicitly] private HwndSource hwndSource = null!;
+#pragma warning restore IDE0052 // Remove unread private members
+
+ private bool isManualDrag;
+
+ private bool isMouseButtonDown;
+
+ private Point mouseDownPosition;
+
+ private Point positionBeforeDrag;
+
+ private Point previousScreenBounds;
+
+ public Button CloseButton { get; private set; } = null!;
+
+ public Grid HeaderBar { get; private set; } = null!;
+
+ public double HeightBeforeMaximize { get; private set; } = 0;
+
+ public Grid LayoutRoot { get; private set; } = null!;
+
+ public Button MaximizeButton { get; private set; } = null!;
+
+ public Button MinimizeButton { get; private set; } = null!;
+
+ public WindowState PreviousState { get; private set; }
+
+ public Button RestoreButton { get; private set; } = null!;
+
+ public double WidthBeforeMaximize { get; private set; } = 0;
+
+ public Grid WindowRoot { get; private set; } = null!;
+
+ static BorderlessWindow()
+ {
+ DefaultStyleKeyProperty.OverrideMetadata(typeof(BorderlessWindow), new FrameworkPropertyMetadata(typeof(BorderlessWindow)));
+ }
+
+ public BorderlessWindow()
+ {
+ double currentDPIScaleFactor = SystemHelper.GetCurrentDPIScaleFactor();
+ Screen screen = Screen.FromHandle(new WindowInteropHelper(this).Handle);
+ this.SizeChanged += this.OnSizeChanged;
+ this.StateChanged += this.OnStateChanged;
+ this.Loaded += this.OnLoaded;
+ Rectangle workingArea = screen.WorkingArea;
+ this.MaxHeight = (workingArea.Height + 16) / currentDPIScaleFactor;
+ SystemEvents.DisplaySettingsChanged += this.SystemEvents_DisplaySettingsChanged;
+ this.AddHandler(MouseLeftButtonUpEvent, new MouseButtonEventHandler(this.OnMouseButtonUp), true);
+ this.AddHandler(MouseMoveEvent, new MouseEventHandler(this.OnMouseMove));
+ }
+
+ public T GetRequiredTemplateChild(string childName) where T : DependencyObject => (T)this.GetTemplateChild(childName);
+
+ public override void OnApplyTemplate()
+ {
+ this.WindowRoot = this.GetRequiredTemplateChild("WindowRoot");
+ this.LayoutRoot = this.GetRequiredTemplateChild("LayoutRoot");
+ this.MinimizeButton = this.GetRequiredTemplateChild