diff --git a/procedural/src/prototype/window.rs b/procedural/src/prototype/window.rs
index 288428f0..15b06a6f 100644
--- a/procedural/src/prototype/window.rs
+++ b/procedural/src/prototype/window.rs
@@ -24,7 +24,7 @@ pub fn derive_prototype_window_struct(
                 #window_class_ref_option
             }
 
-            fn to_window(&self, window_cache: &crate::interface::WindowCache, interface_settings: &crate::interface::InterfaceSettings, available_space: crate::interface::Size) -> crate::interface::Window {
+            fn to_window(&self, window_cache: &crate::interface::WindowCache, interface_settings: &crate::interface::InterfaceSettings, available_space: crate::interface::ScreenSize) -> crate::interface::Window {
                 let scroll_view = crate::interface::ScrollView::new(vec![#(#initializers),*], constraint!(100%, ?));
                 let elements: Vec<crate::interface::ElementCell> = vec![std::rc::Rc::new(std::cell::RefCell::new(scroll_view))];
 
diff --git a/src/graphics/cameras/debug.rs b/src/graphics/cameras/debug.rs
index a3ad040d..c7d56056 100644
--- a/src/graphics/cameras/debug.rs
+++ b/src/graphics/cameras/debug.rs
@@ -4,6 +4,7 @@ use cgmath::{Array, EuclideanSpace, InnerSpace, Matrix4, MetricSpace, Point3, Ra
 
 use super::Camera;
 use crate::graphics::Transform;
+use crate::interface::{ScreenPosition, ScreenSize};
 
 const LOOK_AROUND_SPEED: f32 = 0.005;
 const FLY_SPEED_FAST: f32 = 1000.0;
@@ -165,12 +166,18 @@ impl Camera for DebugCamera {
         (top_left_position, bottom_right_position)
     }
 
-    fn screen_position_size(&self, top_left_position: Vector4<f32>, bottom_right_position: Vector4<f32>) -> (Vector2<f32>, Vector2<f32>) {
+    fn screen_position_size(&self, top_left_position: Vector4<f32>, bottom_right_position: Vector4<f32>) -> (ScreenPosition, ScreenSize) {
         let top_left_position = self.clip_to_screen_space(top_left_position);
         let bottom_right_position = self.clip_to_screen_space(bottom_right_position);
 
-        let screen_position = top_left_position;
-        let screen_size = bottom_right_position - top_left_position;
+        let screen_position = ScreenPosition {
+            left: top_left_position.x,
+            top: top_left_position.y,
+        };
+        let screen_size = ScreenSize {
+            width: bottom_right_position.x - top_left_position.x,
+            height: bottom_right_position.y - top_left_position.y,
+        };
 
         (screen_position, screen_size)
     }
diff --git a/src/graphics/cameras/mod.rs b/src/graphics/cameras/mod.rs
index 78c503d9..8732c41a 100644
--- a/src/graphics/cameras/mod.rs
+++ b/src/graphics/cameras/mod.rs
@@ -12,6 +12,7 @@ pub use self::player::PlayerCamera;
 pub use self::shadow::ShadowCamera;
 pub use self::start::StartCamera;
 use crate::graphics::{SmoothedValue, Transform};
+use crate::interface::{ScreenPosition, ScreenSize};
 
 fn direction(vector: Vector2<f32>) -> usize {
     let inverted = false;
@@ -34,7 +35,7 @@ pub trait Camera {
 
     fn billboard_coordinates(&self, position: Vector3<f32>, size: f32) -> (Vector4<f32>, Vector4<f32>);
 
-    fn screen_position_size(&self, top_left_position: Vector4<f32>, bottom_right_position: Vector4<f32>) -> (Vector2<f32>, Vector2<f32>);
+    fn screen_position_size(&self, top_left_position: Vector4<f32>, bottom_right_position: Vector4<f32>) -> (ScreenPosition, ScreenSize);
 
     fn distance_to(&self, position: Vector3<f32>) -> f32;
 
diff --git a/src/graphics/cameras/player.rs b/src/graphics/cameras/player.rs
index cef7722c..4b28eb7b 100644
--- a/src/graphics/cameras/player.rs
+++ b/src/graphics/cameras/player.rs
@@ -4,6 +4,7 @@ use cgmath::{Array, EuclideanSpace, InnerSpace, Matrix4, MetricSpace, Point3, Ra
 
 use super::{Camera, SmoothedValue};
 use crate::graphics::Transform;
+use crate::interface::{ScreenPosition, ScreenSize};
 
 const ZOOM_SPEED: f32 = 2.0;
 const ROTATION_SPEED: f32 = 0.02;
@@ -162,12 +163,18 @@ impl Camera for PlayerCamera {
         (top_left_position, bottom_right_position)
     }
 
-    fn screen_position_size(&self, top_left_position: Vector4<f32>, bottom_right_position: Vector4<f32>) -> (Vector2<f32>, Vector2<f32>) {
+    fn screen_position_size(&self, top_left_position: Vector4<f32>, bottom_right_position: Vector4<f32>) -> (ScreenPosition, ScreenSize) {
         let top_left_position = self.clip_to_screen_space(top_left_position);
         let bottom_right_position = self.clip_to_screen_space(bottom_right_position);
 
-        let screen_position = top_left_position;
-        let screen_size = bottom_right_position - top_left_position;
+        let screen_position = ScreenPosition {
+            left: top_left_position.x,
+            top: top_left_position.y,
+        };
+        let screen_size = ScreenSize {
+            width: bottom_right_position.x - top_left_position.x,
+            height: bottom_right_position.y - top_left_position.y,
+        };
 
         (screen_position, screen_size)
     }
diff --git a/src/graphics/cameras/shadow.rs b/src/graphics/cameras/shadow.rs
index e316cb9f..6cdcde1e 100644
--- a/src/graphics/cameras/shadow.rs
+++ b/src/graphics/cameras/shadow.rs
@@ -2,6 +2,7 @@ use cgmath::{Array, EuclideanSpace, InnerSpace, Matrix4, MetricSpace, Point3, Sq
 
 use super::Camera;
 use crate::graphics::Transform;
+use crate::interface::{ScreenPosition, ScreenSize};
 
 pub struct ShadowCamera {
     focus_point: Point3<f32>,
@@ -120,12 +121,18 @@ impl Camera for ShadowCamera {
         (top_left_position, bottom_right_position)
     }
 
-    fn screen_position_size(&self, top_left_position: Vector4<f32>, bottom_right_position: Vector4<f32>) -> (Vector2<f32>, Vector2<f32>) {
+    fn screen_position_size(&self, top_left_position: Vector4<f32>, bottom_right_position: Vector4<f32>) -> (ScreenPosition, ScreenSize) {
         let top_left_position = self.clip_to_screen_space(top_left_position);
         let bottom_right_position = self.clip_to_screen_space(bottom_right_position);
 
-        let screen_position = top_left_position;
-        let screen_size = bottom_right_position - top_left_position;
+        let screen_position = ScreenPosition {
+            left: top_left_position.x,
+            top: top_left_position.y,
+        };
+        let screen_size = ScreenSize {
+            width: bottom_right_position.x - top_left_position.x,
+            height: bottom_right_position.y - top_left_position.y,
+        };
 
         (screen_position, screen_size)
     }
diff --git a/src/graphics/cameras/start.rs b/src/graphics/cameras/start.rs
index 3cf03c86..427be54a 100644
--- a/src/graphics/cameras/start.rs
+++ b/src/graphics/cameras/start.rs
@@ -4,6 +4,7 @@ use cgmath::{Array, EuclideanSpace, InnerSpace, Matrix4, MetricSpace, Point3, Ra
 
 use super::Camera;
 use crate::graphics::Transform;
+use crate::interface::{ScreenPosition, ScreenSize};
 
 const DEFAULT_ZOOM: f32 = 150.0;
 const ROTATION_SPEED: f32 = 0.03;
@@ -132,12 +133,18 @@ impl Camera for StartCamera {
         (top_left_position, bottom_right_position)
     }
 
-    fn screen_position_size(&self, top_left_position: Vector4<f32>, bottom_right_position: Vector4<f32>) -> (Vector2<f32>, Vector2<f32>) {
+    fn screen_position_size(&self, top_left_position: Vector4<f32>, bottom_right_position: Vector4<f32>) -> (ScreenPosition, ScreenSize) {
         let top_left_position = self.clip_to_screen_space(top_left_position);
         let bottom_right_position = self.clip_to_screen_space(bottom_right_position);
 
-        let screen_position = top_left_position;
-        let screen_size = bottom_right_position - top_left_position;
+        let screen_position = ScreenPosition {
+            left: top_left_position.x,
+            top: top_left_position.y,
+        };
+        let screen_size = ScreenSize {
+            width: bottom_right_position.x - top_left_position.x,
+            height: bottom_right_position.y - top_left_position.y,
+        };
 
         (screen_position, screen_size)
     }
diff --git a/src/graphics/color.rs b/src/graphics/color.rs
index 60de257f..b8b7078c 100644
--- a/src/graphics/color.rs
+++ b/src/graphics/color.rs
@@ -106,6 +106,18 @@ impl Color {
     }
 }
 
+impl From<Color> for [f32; 3] {
+    fn from(val: Color) -> Self {
+        [val.red_f32(), val.green_f32(), val.blue_f32()]
+    }
+}
+
+impl From<Color> for [f32; 4] {
+    fn from(val: Color) -> Self {
+        [val.red_f32(), val.green_f32(), val.blue_f32(), val.alpha_f32()]
+    }
+}
+
 #[allow(dead_code)]
 #[derive(Clone, Debug, Named, ByteConvertable, PrototypeElement)]
 pub struct ColorBGRA {
diff --git a/src/graphics/particles/mod.rs b/src/graphics/particles/mod.rs
index 93105b55..9c2f5031 100644
--- a/src/graphics/particles/mod.rs
+++ b/src/graphics/particles/mod.rs
@@ -1,11 +1,12 @@
 use std::collections::HashMap;
 
-use cgmath::{Array, Vector2, Vector3, Vector4, Zero};
+use cgmath::{Vector2, Vector3};
 use derive_new::new;
 use procedural::profile;
 use rand::{thread_rng, Rng};
 
 use crate::graphics::*;
+use crate::interface::{ScreenClip, ScreenPosition, ScreenSize};
 use crate::loaders::{GameFileLoader, TextureLoader};
 use crate::network::{EntityId, QuestColor, QuestEffectPacket};
 use crate::world::*;
@@ -18,7 +19,7 @@ pub trait Particle {
         render_target: &mut <DeferredRenderer as Renderer>::Target,
         renderer: &DeferredRenderer,
         camera: &dyn Camera,
-        window_size: Vector2<f32>,
+        window_size: ScreenSize,
     );
 }
 
@@ -53,7 +54,7 @@ impl Particle for DamageNumber {
         render_target: &mut <DeferredRenderer as Renderer>::Target,
         renderer: &DeferredRenderer,
         camera: &dyn Camera,
-        window_size: Vector2<f32>,
+        window_size: ScreenSize,
     ) {
         let (view_matrix, projection_matrix) = camera.view_projection_matrices();
         let clip_space_position = (projection_matrix * view_matrix) * self.position.extend(1.0);
@@ -62,7 +63,10 @@ impl Particle for DamageNumber {
             clip_space_position.y / clip_space_position.w + 1.0,
         );
         let screen_position = screen_position / 2.0;
-        let final_position = Vector2::new(screen_position.x * window_size.x, screen_position.y * window_size.y);
+        let final_position = ScreenPosition {
+            left: screen_position.x * window_size.width,
+            top: screen_position.y * window_size.height,
+        };
 
         renderer.render_damage_text(render_target, &self.damage_amount, final_position, Color::monochrome(255), 16.0);
     }
@@ -93,7 +97,7 @@ impl Particle for HealNumber {
         render_target: &mut <DeferredRenderer as Renderer>::Target,
         renderer: &DeferredRenderer,
         camera: &dyn Camera,
-        window_size: Vector2<f32>,
+        window_size: ScreenSize,
     ) {
         let (view_matrix, projection_matrix) = camera.view_projection_matrices();
         let clip_space_position = (projection_matrix * view_matrix) * self.position.extend(1.0);
@@ -102,7 +106,10 @@ impl Particle for HealNumber {
             clip_space_position.y / clip_space_position.w + 1.0,
         );
         let screen_position = screen_position / 2.0;
-        let final_position = Vector2::new(screen_position.x * window_size.x, screen_position.y * window_size.y);
+        let final_position = ScreenPosition {
+            left: screen_position.x * window_size.width,
+            top: screen_position.y * window_size.height,
+        };
 
         renderer.render_damage_text(render_target, &self.heal_amount, final_position, Color::rgb(30, 255, 30), 16.0);
     }
@@ -144,7 +151,7 @@ impl QuestIcon {
         render_target: &mut <DeferredRenderer as Renderer>::Target,
         renderer: &DeferredRenderer,
         camera: &dyn Camera,
-        window_size: Vector2<f32>,
+        window_size: ScreenSize,
     ) {
         let (view_matrix, projection_matrix) = camera.view_projection_matrices();
         let clip_space_position = (projection_matrix * view_matrix) * self.position.extend(1.0);
@@ -153,14 +160,17 @@ impl QuestIcon {
             clip_space_position.y / clip_space_position.w + 1.0,
         );
         let screen_position = screen_position / 2.0;
-        let final_position = Vector2::new(screen_position.x * window_size.x, screen_position.y * window_size.y);
+        let final_position = ScreenPosition {
+            left: screen_position.x * window_size.width,
+            top: screen_position.y * window_size.height,
+        };
 
         renderer.render_sprite(
             render_target,
             self.texture.clone(),
-            final_position - Vector2::from_value(15.0),
-            Vector2::from_value(30.0),
-            Vector4::zero(),
+            final_position - ScreenSize::uniform(15.0),
+            ScreenSize::uniform(30.0),
+            ScreenClip::default(),
             self.color,
             true,
         );
@@ -211,7 +221,7 @@ impl ParticleHolder {
         render_target: &mut <DeferredRenderer as Renderer>::Target,
         renderer: &DeferredRenderer,
         camera: &dyn Camera,
-        window_size: Vector2<f32>,
+        window_size: ScreenSize,
         entities: &[Entity],
     ) {
         self.particles
diff --git a/src/graphics/renderers/deferred/ambient/mod.rs b/src/graphics/renderers/deferred/ambient/mod.rs
index e2918c48..5b379d82 100644
--- a/src/graphics/renderers/deferred/ambient/mod.rs
+++ b/src/graphics/renderers/deferred/ambient/mod.rs
@@ -77,9 +77,7 @@ impl AmbientLightRenderer {
             WriteDescriptorSet::image_view(1, render_target.normal_image.clone()),
         ]);
 
-        let constants = Constants {
-            color: [color.red_f32(), color.green_f32(), color.blue_f32()],
-        };
+        let constants = Constants { color: color.into() };
 
         render_target
             .state
diff --git a/src/graphics/renderers/deferred/box/mod.rs b/src/graphics/renderers/deferred/box/mod.rs
index 486e0e92..4214a88a 100644
--- a/src/graphics/renderers/deferred/box/mod.rs
+++ b/src/graphics/renderers/deferred/box/mod.rs
@@ -139,7 +139,7 @@ impl BoxRenderer {
 
         let constants = Constants {
             world: world_matrix.into(),
-            color: [color.red_f32(), color.green_f32(), color.blue_f32()],
+            color: color.into(),
         };
 
         render_target
diff --git a/src/graphics/renderers/deferred/directional/mod.rs b/src/graphics/renderers/deferred/directional/mod.rs
index 7b944a1a..2b678c42 100644
--- a/src/graphics/renderers/deferred/directional/mod.rs
+++ b/src/graphics/renderers/deferred/directional/mod.rs
@@ -104,7 +104,7 @@ impl DirectionalLightRenderer {
         ]);
 
         let constants = Constants {
-            direction: Padded([direction.x, direction.y, direction.z]),
+            direction: Padded(direction.into()),
             color: [
                 color.red_f32() * intensity,
                 color.green_f32() * intensity,
diff --git a/src/graphics/renderers/deferred/effect/mod.rs b/src/graphics/renderers/deferred/effect/mod.rs
index 59b360a6..03c36eba 100644
--- a/src/graphics/renderers/deferred/effect/mod.rs
+++ b/src/graphics/renderers/deferred/effect/mod.rs
@@ -18,6 +18,7 @@ use super::DeferredSubrenderer;
 use crate::graphics::renderers::pipeline::PipelineBuilder;
 use crate::graphics::renderers::sampler::{create_new_sampler, SamplerType};
 use crate::graphics::*;
+use crate::interface::ScreenSize;
 
 pub struct EffectRenderer {
     memory_allocator: Arc<MemoryAllocator>,
@@ -76,7 +77,7 @@ impl EffectRenderer {
         &self,
         render_target: &mut <DeferredRenderer as Renderer>::Target,
         texture: Arc<ImageView>,
-        window_size: Vector2<usize>,
+        window_size: ScreenSize,
         mut screen_positions: [Vector2<f32>; 4],
         texture_coordinates: [Vector2<f32>; 4],
         screen_space_position: Vector2<f32>,
@@ -90,7 +91,7 @@ impl EffectRenderer {
             self.bind_pipeline(render_target);
         }
 
-        let half_screen = Vector2::new(window_size.x as f32 / 2.0, window_size.y as f32 / 2.0);
+        let half_screen = Vector2::new(window_size.width / 2.0, window_size.height / 2.0);
 
         // TODO: move this calculation to the loading
         let rotation_matrix = Matrix2::from_angle(cgmath::Deg(angle / (1024.0 / 360.0)));
@@ -122,7 +123,7 @@ impl EffectRenderer {
             t_bottom_left: texture_coordinates[3],
             t_top_right: texture_coordinates[1],
             t_bottom_right: texture_coordinates[0],
-            color: [color.red_f32(), color.green_f32(), color.blue_f32(), color.alpha_f32()],
+            color: color.into(),
         };
 
         render_target
diff --git a/src/graphics/renderers/deferred/entity/mod.rs b/src/graphics/renderers/deferred/entity/mod.rs
index 963afbab..06f0606a 100644
--- a/src/graphics/renderers/deferred/entity/mod.rs
+++ b/src/graphics/renderers/deferred/entity/mod.rs
@@ -122,8 +122,8 @@ impl EntityRenderer {
 
         let constants = Constants {
             world: world_matrix.into(),
-            texture_position: [texture_position.x, texture_position.y],
-            texture_size: [texture_size.x, texture_size.y],
+            texture_position: texture_position.into(),
+            texture_size: texture_size.into(),
             depth_offset,
             curvature,
             mirror: mirror as u32,
diff --git a/src/graphics/renderers/deferred/indicator/mod.rs b/src/graphics/renderers/deferred/indicator/mod.rs
index e023de6c..a00b526f 100644
--- a/src/graphics/renderers/deferred/indicator/mod.rs
+++ b/src/graphics/renderers/deferred/indicator/mod.rs
@@ -109,7 +109,7 @@ impl IndicatorRenderer {
         ]);
 
         let constants = Constants {
-            color: Padded([color.red_f32(), color.green_f32(), color.blue_f32()]),
+            color: Padded(color.into()),
             upper_left: Padded(upper_left.into()),
             upper_right: Padded(upper_right.into()),
             lower_left: Padded(lower_left.into()),
diff --git a/src/graphics/renderers/deferred/mod.rs b/src/graphics/renderers/deferred/mod.rs
index dcc46f31..85f3c6b9 100644
--- a/src/graphics/renderers/deferred/mod.rs
+++ b/src/graphics/renderers/deferred/mod.rs
@@ -19,7 +19,7 @@ use std::sync::Arc;
 
 #[cfg(feature = "debug")]
 use cgmath::SquareMatrix;
-use cgmath::{Matrix4, Vector2, Vector3, Vector4};
+use cgmath::{Matrix4, Vector2, Vector3};
 use procedural::profile;
 use vulkano::device::{DeviceOwned, Queue};
 use vulkano::format::Format;
@@ -49,6 +49,7 @@ use crate::graphics::{
     EntityRenderer as EntityRendererTrait, GeometryRenderer as GeometryRendererTrait, IndicatorRenderer as IndicatorRendererTrait,
     SpriteRenderer as SpriteRendererTrait, *,
 };
+use crate::interface::{ScreenClip, ScreenPosition, ScreenSize};
 use crate::loaders::{GameFileLoader, TextureLoader};
 use crate::network::EntityId;
 #[cfg(feature = "debug")]
@@ -344,29 +345,38 @@ impl DeferredRenderer {
         self.overlay_renderer.render(render_target, interface_image);
     }
 
+    fn get_window_size(&self) -> ScreenSize {
+        ScreenSize {
+            width: self.dimensions[0] as f32,
+            height: self.dimensions[1] as f32,
+        }
+    }
+
     pub fn render_rectangle(
         &self,
         render_target: &mut <Self as Renderer>::Target,
-        position: Vector2<f32>,
-        size: Vector2<f32>,
+        position: ScreenPosition,
+        size: ScreenSize,
         color: Color,
     ) {
-        let window_size = Vector2::new(self.dimensions[0] as usize, self.dimensions[1] as usize);
-
-        self.rectangle_renderer.render(render_target, window_size, position, size, color);
+        self.rectangle_renderer
+            .render(render_target, self.get_window_size(), position, size, color);
     }
 
     pub fn render_bar(
         &self,
         render_target: &mut <Self as Renderer>::Target,
-        position: Vector2<f32>,
-        size: Vector2<f32>,
+        position: ScreenPosition,
+        size: ScreenSize,
         color: Color,
         maximum: f32,
         current: f32,
     ) {
-        let bar_offset = Vector2::new(size.x / 2.0, 0.0);
-        let bar_size = Vector2::new((size.x / maximum) * current, size.y);
+        let bar_offset = ScreenSize::only_width(size.width / 2.0);
+        let bar_size = ScreenSize {
+            width: (size.width / maximum) * current,
+            height: size.height,
+        };
 
         self.render_rectangle(render_target, position - bar_offset, bar_size, color);
     }
@@ -375,11 +385,11 @@ impl DeferredRenderer {
         &self,
         render_target: &mut <Self as Renderer>::Target,
         text: &str,
-        mut position: Vector2<f32>,
+        mut position: ScreenPosition,
         color: Color,
         font_size: f32,
     ) {
-        let window_size = Vector2::new(self.dimensions[0] as usize, self.dimensions[1] as usize);
+        let window_size = self.get_window_size();
 
         for character in text.as_bytes() {
             let index = (*character as usize).saturating_sub(31);
@@ -388,13 +398,13 @@ impl DeferredRenderer {
                 self.font_map.clone(),
                 window_size,
                 position,
-                Vector2::new(font_size, font_size),
+                ScreenSize::uniform(font_size),
                 color,
                 10,
                 index,
                 true,
             );
-            position.x += font_size / 2.0;
+            position.left += font_size / 2.0;
         }
     }
 
@@ -402,11 +412,11 @@ impl DeferredRenderer {
         &self,
         render_target: &mut <Self as Renderer>::Target,
         text: &str,
-        mut position: Vector2<f32>,
+        mut position: ScreenPosition,
         color: Color,
         font_size: f32,
     ) {
-        let window_size = Vector2::new(self.dimensions[0] as usize, self.dimensions[1] as usize);
+        let window_size = self.get_window_size();
 
         for character in text.as_bytes() {
             let index = (*character as usize).saturating_sub(31);
@@ -415,13 +425,13 @@ impl DeferredRenderer {
                 self.font_map.clone(),
                 window_size,
                 position,
-                Vector2::new(font_size, font_size),
+                ScreenSize::uniform(font_size),
                 color,
                 10,
                 index,
                 true,
             );
-            position.x += font_size / 2.0;
+            position.left += font_size / 2.0;
         }
     }
 
@@ -436,7 +446,7 @@ impl DeferredRenderer {
         angle: f32,
         color: Color,
     ) {
-        let window_size = Vector2::new(self.dimensions[0] as usize, self.dimensions[1] as usize);
+        let window_size = self.get_window_size();
 
         self.effect_renderer.render(
             render_target,
@@ -552,18 +562,25 @@ impl SpriteRendererTrait for DeferredRenderer {
         &self,
         render_target: &mut <Self as Renderer>::Target,
         texture: Arc<ImageView>,
-        position: Vector2<f32>,
-        size: Vector2<f32>,
-        _clip_size: Vector4<f32>,
+        position: ScreenPosition,
+        size: ScreenSize,
+        _screen_clip: ScreenClip,
         color: Color,
         smooth: bool,
     ) where
         Self: Renderer,
     {
-        let window_size = Vector2::new(self.dimensions[0] as usize, self.dimensions[1] as usize);
-
-        self.sprite_renderer
-            .render_indexed(render_target, texture, window_size, position, size, color, 1, 0, smooth);
+        self.sprite_renderer.render_indexed(
+            render_target,
+            texture,
+            self.get_window_size(),
+            position,
+            size,
+            color,
+            1,
+            0,
+            smooth,
+        );
     }
 }
 
diff --git a/src/graphics/renderers/deferred/point/mod.rs b/src/graphics/renderers/deferred/point/mod.rs
index 0116a9be..24d78975 100644
--- a/src/graphics/renderers/deferred/point/mod.rs
+++ b/src/graphics/renderers/deferred/point/mod.rs
@@ -108,10 +108,10 @@ impl PointLightRenderer {
         let (screen_position, screen_size) = camera.screen_position_size(top_left_position, bottom_right_position);
 
         let constants = Constants {
-            screen_position: [screen_position.x, screen_position.y],
-            screen_size: [screen_size.x, screen_size.y],
-            position: Padded([position.x, position.y, position.z]),
-            color: [color.red_f32(), color.green_f32(), color.blue_f32()],
+            screen_position: screen_position.into(),
+            screen_size: screen_size.into(),
+            position: Padded(position.into()),
+            color: color.into(),
             range,
         };
 
diff --git a/src/graphics/renderers/deferred/rectangle/mod.rs b/src/graphics/renderers/deferred/rectangle/mod.rs
index c071fd9d..55f0ecd5 100644
--- a/src/graphics/renderers/deferred/rectangle/mod.rs
+++ b/src/graphics/renderers/deferred/rectangle/mod.rs
@@ -3,7 +3,6 @@ fragment_shader!("src/graphics/renderers/deferred/rectangle/fragment_shader.glsl
 
 use std::sync::Arc;
 
-use cgmath::Vector2;
 use procedural::profile;
 use vulkano::device::{Device, DeviceOwned};
 use vulkano::pipeline::graphics::viewport::Viewport;
@@ -15,6 +14,7 @@ use self::vertex_shader::Constants;
 use super::DeferredSubrenderer;
 use crate::graphics::renderers::pipeline::PipelineBuilder;
 use crate::graphics::*;
+use crate::interface::{ScreenPosition, ScreenSize};
 
 pub struct RectangleRenderer {
     vertex_shader: EntryPoint,
@@ -67,9 +67,9 @@ impl RectangleRenderer {
     pub fn render(
         &self,
         render_target: &mut <DeferredRenderer as Renderer>::Target,
-        window_size: Vector2<usize>,
-        screen_position: Vector2<f32>,
-        screen_size: Vector2<f32>,
+        window_size: ScreenSize,
+        screen_position: ScreenPosition,
+        screen_size: ScreenSize,
         color: Color,
     ) {
         if render_target.bind_subrenderer(DeferredSubrenderer::Rectangle) {
@@ -78,14 +78,14 @@ impl RectangleRenderer {
 
         let layout = self.pipeline.layout().clone();
 
-        let half_screen = Vector2::new(window_size.x as f32 / 2.0, window_size.y as f32 / 2.0);
-        let screen_position = Vector2::new(screen_position.x / half_screen.x, screen_position.y / half_screen.y);
-        let screen_size = Vector2::new(screen_size.x / half_screen.x, screen_size.y / half_screen.y);
+        let half_screen = window_size / 2.0;
+        let screen_position = screen_position / half_screen;
+        let screen_size = screen_size / half_screen;
 
         let constants = Constants {
             screen_position: screen_position.into(),
             screen_size: screen_size.into(),
-            color: [color.red_f32(), color.green_f32(), color.blue_f32(), color.alpha_f32()],
+            color: color.into(),
         };
 
         render_target
diff --git a/src/graphics/renderers/deferred/sprite/mod.rs b/src/graphics/renderers/deferred/sprite/mod.rs
index 4b424fab..72b93205 100644
--- a/src/graphics/renderers/deferred/sprite/mod.rs
+++ b/src/graphics/renderers/deferred/sprite/mod.rs
@@ -18,6 +18,7 @@ use super::DeferredSubrenderer;
 use crate::graphics::renderers::pipeline::PipelineBuilder;
 use crate::graphics::renderers::sampler::{create_new_sampler, SamplerType};
 use crate::graphics::*;
+use crate::interface::{ScreenPosition, ScreenSize};
 #[cfg(feature = "debug")]
 use crate::loaders::{GameFileLoader, TextureLoader};
 #[cfg(feature = "debug")]
@@ -120,8 +121,8 @@ impl SpriteRenderer {
         &self,
         render_target: &mut <DeferredRenderer as Renderer>::Target,
         texture: Arc<ImageView>,
-        screen_position: Vector2<f32>,
-        screen_size: Vector2<f32>,
+        screen_position: ScreenPosition,
+        screen_size: ScreenSize,
         texture_position: Vector2<f32>,
         texture_size: Vector2<f32>,
         color: Color,
@@ -141,11 +142,11 @@ impl SpriteRenderer {
         ]);
 
         let constants = Constants {
-            screen_position: [screen_position.x, screen_position.y],
-            screen_size: [screen_size.x, screen_size.y],
-            texture_position: [texture_position.x, texture_position.y],
-            texture_size: [texture_size.x, texture_size.y],
-            color: [color.red_f32(), color.green_f32(), color.blue_f32(), color.alpha_f32()],
+            screen_position: screen_position.into(),
+            screen_size: screen_size.into(),
+            texture_position: texture_position.into(),
+            texture_size: texture_size.into(),
+            color: color.into(),
         };
 
         render_target
@@ -164,17 +165,26 @@ impl SpriteRenderer {
         &self,
         render_target: &mut <DeferredRenderer as Renderer>::Target,
         texture: Arc<ImageView>,
-        window_size: Vector2<usize>,
-        screen_position: Vector2<f32>,
-        screen_size: Vector2<f32>,
+        window_size: ScreenSize,
+        screen_position: ScreenPosition,
+        screen_size: ScreenSize,
         color: Color,
         column_count: usize,
         cell_index: usize,
         smooth: bool,
     ) {
-        let half_screen = Vector2::new(window_size.x as f32 / 2.0, window_size.y as f32 / 2.0);
-        let screen_position = Vector2::new(screen_position.x / half_screen.x, screen_position.y / half_screen.y);
-        let screen_size = Vector2::new(screen_size.x / half_screen.x, screen_size.y / half_screen.y);
+        let half_screen = ScreenSize {
+            width: window_size.width as f32 / 2.0,
+            height: window_size.height as f32 / 2.0,
+        };
+        let screen_position = ScreenPosition {
+            left: screen_position.left / half_screen.width,
+            top: screen_position.top / half_screen.height,
+        };
+        let screen_size = ScreenSize {
+            width: screen_size.width / half_screen.width,
+            height: screen_size.height / half_screen.height,
+        };
 
         let unit = 1.0 / column_count as f32;
         let offset_x = unit * (cell_index % column_count) as f32;
@@ -198,8 +208,8 @@ impl SpriteRenderer {
         &self,
         render_target: &mut <DeferredRenderer as Renderer>::Target,
         marker_identifier: MarkerIdentifier,
-        screen_position: Vector2<f32>,
-        screen_size: Vector2<f32>,
+        screen_position: ScreenPosition,
+        screen_size: ScreenSize,
         hovered: bool,
     ) {
         let (texture, color) = match marker_identifier {
diff --git a/src/graphics/renderers/interface/mod.rs b/src/graphics/renderers/interface/mod.rs
index b75f0d36..22b3419d 100644
--- a/src/graphics/renderers/interface/mod.rs
+++ b/src/graphics/renderers/interface/mod.rs
@@ -6,7 +6,7 @@ use std::cell::RefCell;
 use std::rc::Rc;
 use std::sync::Arc;
 
-use cgmath::{Vector2, Vector4};
+use cgmath::Vector2;
 use procedural::profile;
 use vulkano::device::{DeviceOwned, Queue};
 use vulkano::format::{ClearColorValue, Format};
@@ -20,6 +20,7 @@ use self::sprite::SpriteRenderer;
 use self::text::TextRenderer;
 use super::{IntoFormat, SubpassAttachments};
 use crate::graphics::{Color, MemoryAllocator, Renderer, SingleRenderTarget, SpriteRenderer as SpriteRendererTrait};
+use crate::interface::{CornerRadius, ScreenClip, ScreenPosition, ScreenSize};
 use crate::loaders::{FontLoader, GameFileLoader, TextureLoader};
 
 #[derive(PartialEq, Eq)]
@@ -132,26 +133,39 @@ impl InterfaceRenderer {
         )
     }
 
+    fn get_window_size(&self) -> ScreenSize {
+        ScreenSize {
+            width: self.dimensions[0] as f32,
+            height: self.dimensions[1] as f32,
+        }
+    }
+
     pub fn render_rectangle(
         &self,
         render_target: &mut <InterfaceRenderer as Renderer>::Target,
-        position: Vector2<f32>,
-        size: Vector2<f32>,
-        clip_size: Vector4<f32>,
-        corner_radius: Vector4<f32>,
+        position: ScreenPosition,
+        size: ScreenSize,
+        screen_clip: ScreenClip,
+        corner_radius: CornerRadius,
         color: Color,
     ) {
-        let window_size = Vector2::new(self.dimensions[0] as usize, self.dimensions[1] as usize);
-        self.rectangle_renderer
-            .render(render_target, window_size, position, size, clip_size, corner_radius, color);
+        self.rectangle_renderer.render(
+            render_target,
+            self.get_window_size(),
+            position,
+            size,
+            screen_clip,
+            corner_radius,
+            color,
+        );
     }
 
     pub fn render_checkbox(
         &self,
         render_target: &mut <InterfaceRenderer as Renderer>::Target,
-        position: Vector2<f32>,
-        size: Vector2<f32>,
-        clip_size: Vector4<f32>,
+        position: ScreenPosition,
+        size: ScreenSize,
+        screen_clip: ScreenClip,
         color: Color,
         checked: bool,
     ) {
@@ -160,15 +174,15 @@ impl InterfaceRenderer {
             false => self.unchecked_box_texture.clone(),
         };
 
-        self.render_sprite(render_target, texture, position, size, clip_size, color, true);
+        self.render_sprite(render_target, texture, position, size, screen_clip, color, true);
     }
 
     pub fn render_expand_arrow(
         &self,
         render_target: &mut <InterfaceRenderer as Renderer>::Target,
-        position: Vector2<f32>,
-        size: Vector2<f32>,
-        clip_size: Vector4<f32>,
+        position: ScreenPosition,
+        size: ScreenSize,
+        screen_clip: ScreenClip,
         color: Color,
         expanded: bool,
     ) {
@@ -177,21 +191,27 @@ impl InterfaceRenderer {
             false => self.collapsed_arrow_texture.clone(),
         };
 
-        self.render_sprite(render_target, texture, position, size, clip_size, color, true);
+        self.render_sprite(render_target, texture, position, size, screen_clip, color, true);
     }
 
     pub fn render_text(
         &self,
         render_target: &mut <InterfaceRenderer as Renderer>::Target,
         text: &str,
-        position: Vector2<f32>,
-        clip_size: Vector4<f32>,
+        position: ScreenPosition,
+        screen_clip: ScreenClip,
         color: Color,
         font_size: f32,
     ) -> f32 {
-        let window_size = Vector2::new(self.dimensions[0] as usize, self.dimensions[1] as usize);
-        self.text_renderer
-            .render(render_target, text, window_size, position, clip_size, color, font_size)
+        self.text_renderer.render(
+            render_target,
+            text,
+            self.get_window_size(),
+            position,
+            screen_clip,
+            color,
+            font_size,
+        )
     }
 }
 
@@ -212,17 +232,23 @@ impl SpriteRendererTrait for InterfaceRenderer {
         &self,
         render_target: &mut <Self as Renderer>::Target,
         texture: Arc<ImageView>,
-        position: Vector2<f32>,
-        size: Vector2<f32>,
-        clip_size: Vector4<f32>,
+        position: ScreenPosition,
+        size: ScreenSize,
+        screen_clip: ScreenClip,
         color: Color,
         smooth: bool,
     ) where
         Self: Renderer,
     {
-        let window_size = Vector2::new(self.dimensions[0] as usize, self.dimensions[1] as usize);
-
-        self.sprite_renderer
-            .render(render_target, texture, window_size, position, size, clip_size, color, smooth);
+        self.sprite_renderer.render(
+            render_target,
+            texture,
+            self.get_window_size(),
+            position,
+            size,
+            screen_clip,
+            color,
+            smooth,
+        );
     }
 }
diff --git a/src/graphics/renderers/interface/rectangle/fragment_shader.glsl b/src/graphics/renderers/interface/rectangle/fragment_shader.glsl
index aca8fdc9..08917fd0 100644
--- a/src/graphics/renderers/interface/rectangle/fragment_shader.glsl
+++ b/src/graphics/renderers/interface/rectangle/fragment_shader.glsl
@@ -7,7 +7,7 @@ layout(location = 0) out vec4 fragment_color;
 layout(push_constant) uniform Constants {
     vec2 screen_position;
     vec2 screen_size;
-    vec4 clip_size;
+    vec4 screen_clip;
     vec4 corner_radius;
     vec4 color;
     float aspect_ratio;
@@ -45,7 +45,7 @@ void main() {
         discard;
     }
 
-    if (gl_FragCoord.x < constants.clip_size.x || gl_FragCoord.y < constants.clip_size.y || gl_FragCoord.x > constants.clip_size.z || gl_FragCoord.y > constants.clip_size.w) {
+    if (gl_FragCoord.x < constants.screen_clip.x || gl_FragCoord.y < constants.screen_clip.y || gl_FragCoord.x > constants.screen_clip.z || gl_FragCoord.y > constants.screen_clip.w) {
         discard;
     }
 
diff --git a/src/graphics/renderers/interface/rectangle/mod.rs b/src/graphics/renderers/interface/rectangle/mod.rs
index 8309e616..4d7cf9ca 100644
--- a/src/graphics/renderers/interface/rectangle/mod.rs
+++ b/src/graphics/renderers/interface/rectangle/mod.rs
@@ -3,7 +3,6 @@ fragment_shader!("src/graphics/renderers/interface/rectangle/fragment_shader.gls
 
 use std::sync::Arc;
 
-use cgmath::{Vector2, Vector4};
 use procedural::profile;
 use vulkano::device::{Device, DeviceOwned};
 use vulkano::image::SampleCount;
@@ -16,6 +15,7 @@ use self::vertex_shader::Constants;
 use super::InterfaceSubrenderer;
 use crate::graphics::renderers::pipeline::PipelineBuilder;
 use crate::graphics::*;
+use crate::interface::{CornerRadius, ScreenClip, ScreenPosition, ScreenSize};
 
 pub struct RectangleRenderer {
     vertex_shader: EntryPoint,
@@ -69,11 +69,11 @@ impl RectangleRenderer {
     pub fn render(
         &self,
         render_target: &mut <InterfaceRenderer as Renderer>::Target,
-        window_size: Vector2<usize>,
-        screen_position: Vector2<f32>,
-        screen_size: Vector2<f32>,
-        clip_size: Vector4<f32>,
-        corner_radius: Vector4<f32>,
+        window_size: ScreenSize,
+        screen_position: ScreenPosition,
+        screen_size: ScreenSize,
+        screen_clip: ScreenClip,
+        corner_radius: CornerRadius,
         color: Color,
     ) {
         if render_target.bind_subrenderer(InterfaceSubrenderer::Rectangle) {
@@ -82,25 +82,20 @@ impl RectangleRenderer {
 
         let layout = self.pipeline.layout().clone();
 
-        let half_screen = Vector2::new(window_size.x as f32 / 2.0, window_size.y as f32 / 2.0);
-        let screen_position = Vector2::new(screen_position.x / half_screen.x, screen_position.y / half_screen.y);
-        let screen_size = Vector2::new(screen_size.x / half_screen.x, screen_size.y / half_screen.y);
+        let half_screen = window_size / 2.0;
+        let screen_position = screen_position / half_screen;
+        let screen_size = screen_size / half_screen;
 
-        let pixel_size = 1.0 / window_size.y as f32;
-        let corner_radius = Vector4::new(
-            corner_radius.x * pixel_size,
-            corner_radius.y * pixel_size,
-            corner_radius.z * pixel_size,
-            corner_radius.w * pixel_size,
-        );
+        let pixel_size = 1.0 / window_size.height;
+        let corner_radius = corner_radius * pixel_size;
 
         let constants = Constants {
             screen_position: screen_position.into(),
             screen_size: screen_size.into(),
-            clip_size: clip_size.into(),
+            screen_clip: screen_clip.into(),
             corner_radius: corner_radius.into(),
-            color: [color.red_f32(), color.green_f32(), color.blue_f32(), color.alpha_f32()],
-            aspect_ratio: window_size.y as f32 / window_size.x as f32,
+            color: color.into(),
+            aspect_ratio: window_size.height / window_size.width,
         };
 
         render_target
diff --git a/src/graphics/renderers/interface/rectangle/vertex_shader.glsl b/src/graphics/renderers/interface/rectangle/vertex_shader.glsl
index 3ab6e46c..f23b6eaa 100644
--- a/src/graphics/renderers/interface/rectangle/vertex_shader.glsl
+++ b/src/graphics/renderers/interface/rectangle/vertex_shader.glsl
@@ -5,7 +5,7 @@ layout(location = 0) out vec2 position_out;
 layout(push_constant) uniform Constants {
     vec2 screen_position;
     vec2 screen_size;
-    vec4 clip_size;
+    vec4 screen_clip;
     vec4 corner_radius;
     vec4 color;
     float aspect_ratio;
diff --git a/src/graphics/renderers/interface/sprite/fragment_shader.glsl b/src/graphics/renderers/interface/sprite/fragment_shader.glsl
index 5096de73..59b61bc3 100644
--- a/src/graphics/renderers/interface/sprite/fragment_shader.glsl
+++ b/src/graphics/renderers/interface/sprite/fragment_shader.glsl
@@ -9,13 +9,13 @@ layout (set = 0, binding = 0) uniform sampler2D sprite_texture;
 layout(push_constant) uniform Constants {
     vec2 screen_position;
     vec2 screen_size;
-    vec4 clip_size;
+    vec4 screen_clip;
     vec4 color;
 } constants;
 
 void main() {
 
-    if (gl_FragCoord.x < constants.clip_size.x || gl_FragCoord.y < constants.clip_size.y || gl_FragCoord.x > constants.clip_size.z || gl_FragCoord.y > constants.clip_size.w) {
+    if (gl_FragCoord.x < constants.screen_clip.x || gl_FragCoord.y < constants.screen_clip.y || gl_FragCoord.x > constants.screen_clip.z || gl_FragCoord.y > constants.screen_clip.w) {
         discard;
     }
 
diff --git a/src/graphics/renderers/interface/sprite/mod.rs b/src/graphics/renderers/interface/sprite/mod.rs
index 117ada4d..f9bec5e1 100644
--- a/src/graphics/renderers/interface/sprite/mod.rs
+++ b/src/graphics/renderers/interface/sprite/mod.rs
@@ -3,7 +3,6 @@ fragment_shader!("src/graphics/renderers/interface/sprite/fragment_shader.glsl")
 
 use std::sync::Arc;
 
-use cgmath::{Vector2, Vector4};
 use procedural::profile;
 use vulkano::descriptor_set::WriteDescriptorSet;
 use vulkano::device::{Device, DeviceOwned};
@@ -19,6 +18,7 @@ use super::InterfaceSubrenderer;
 use crate::graphics::renderers::pipeline::PipelineBuilder;
 use crate::graphics::renderers::sampler::{create_new_sampler, SamplerType};
 use crate::graphics::*;
+use crate::interface::{ScreenClip, ScreenPosition, ScreenSize};
 
 pub struct SpriteRenderer {
     memory_allocator: Arc<MemoryAllocator>,
@@ -81,10 +81,10 @@ impl SpriteRenderer {
         &self,
         render_target: &mut <InterfaceRenderer as Renderer>::Target,
         texture: Arc<ImageView>,
-        window_size: Vector2<usize>,
-        screen_position: Vector2<f32>,
-        screen_size: Vector2<f32>,
-        clip_size: Vector4<f32>,
+        window_size: ScreenSize,
+        screen_position: ScreenPosition,
+        screen_size: ScreenSize,
+        screen_clip: ScreenClip,
         color: Color,
         smooth: bool,
     ) {
@@ -92,9 +92,9 @@ impl SpriteRenderer {
             self.bind_pipeline(render_target);
         }
 
-        let half_screen = Vector2::new(window_size.x as f32 / 2.0, window_size.y as f32 / 2.0);
-        let screen_position = Vector2::new(screen_position.x / half_screen.x, screen_position.y / half_screen.y);
-        let screen_size = Vector2::new(screen_size.x / half_screen.x, screen_size.y / half_screen.y);
+        let half_screen = window_size / 2.0;
+        let screen_position = screen_position / half_screen;
+        let screen_size = screen_size / half_screen;
 
         let sampler = match smooth {
             true => self.linear_sampler.clone(),
@@ -108,8 +108,8 @@ impl SpriteRenderer {
         let constants = Constants {
             screen_position: screen_position.into(),
             screen_size: screen_size.into(),
-            clip_size: clip_size.into(),
-            color: [color.red_f32(), color.green_f32(), color.blue_f32(), color.alpha_f32()],
+            screen_clip: screen_clip.into(),
+            color: color.into(),
         };
 
         render_target
diff --git a/src/graphics/renderers/interface/sprite/vertex_shader.glsl b/src/graphics/renderers/interface/sprite/vertex_shader.glsl
index 0ece11b1..f692b825 100644
--- a/src/graphics/renderers/interface/sprite/vertex_shader.glsl
+++ b/src/graphics/renderers/interface/sprite/vertex_shader.glsl
@@ -5,7 +5,7 @@ layout(location = 0) out vec2 texture_coordinates;
 layout(push_constant) uniform Constants {
     vec2 screen_position;
     vec2 screen_size;
-    vec4 clip_size;
+    vec4 screen_clip;
     vec4 color;
 } constants;
 
diff --git a/src/graphics/renderers/interface/text/fragment_shader.glsl b/src/graphics/renderers/interface/text/fragment_shader.glsl
index 61858c84..c5722489 100644
--- a/src/graphics/renderers/interface/text/fragment_shader.glsl
+++ b/src/graphics/renderers/interface/text/fragment_shader.glsl
@@ -9,7 +9,7 @@ layout (set = 0, binding = 0) uniform sampler2D sprite_texture;
 layout(push_constant) uniform Constants {
     vec2 screen_position;
     vec2 screen_size;
-    vec4 clip_size;
+    vec4 screen_clip;
     vec2 texture_position;
     vec2 texture_size;
     vec4 color;
@@ -17,7 +17,7 @@ layout(push_constant) uniform Constants {
 
 void main() {
 
-    if (gl_FragCoord.x < constants.clip_size.x || gl_FragCoord.y < constants.clip_size.y || gl_FragCoord.x > constants.clip_size.z || gl_FragCoord.y > constants.clip_size.w) {
+    if (gl_FragCoord.x < constants.screen_clip.x || gl_FragCoord.y < constants.screen_clip.y || gl_FragCoord.x > constants.screen_clip.z || gl_FragCoord.y > constants.screen_clip.w) {
         discard;
     }
 
diff --git a/src/graphics/renderers/interface/text/mod.rs b/src/graphics/renderers/interface/text/mod.rs
index 359bd973..b08fdf89 100644
--- a/src/graphics/renderers/interface/text/mod.rs
+++ b/src/graphics/renderers/interface/text/mod.rs
@@ -5,7 +5,6 @@ use std::cell::RefCell;
 use std::rc::Rc;
 use std::sync::Arc;
 
-use cgmath::{Vector2, Vector4};
 use procedural::profile;
 use vulkano::descriptor_set::WriteDescriptorSet;
 use vulkano::device::{Device, DeviceOwned};
@@ -21,6 +20,7 @@ use super::InterfaceSubrenderer;
 use crate::graphics::renderers::pipeline::PipelineBuilder;
 use crate::graphics::renderers::sampler::{create_new_sampler, SamplerType};
 use crate::graphics::*;
+use crate::interface::{ScreenClip, ScreenPosition, ScreenSize};
 use crate::loaders::FontLoader;
 
 pub struct TextRenderer {
@@ -83,9 +83,9 @@ impl TextRenderer {
         &self,
         render_target: &mut <InterfaceRenderer as Renderer>::Target,
         text: &str,
-        window_size: Vector2<usize>,
-        screen_position: Vector2<f32>,
-        clip_size: Vector4<f32>,
+        window_size: ScreenSize,
+        screen_position: ScreenPosition,
+        screen_clip: ScreenClip,
         color: Color,
         font_size: f32,
     ) -> f32 {
@@ -95,8 +95,8 @@ impl TextRenderer {
 
         let mut font_loader = self.font_loader.borrow_mut();
         let texture = font_loader.get_font_atlas();
-        let (character_layout, heigth) = font_loader.get(text, color, font_size, clip_size.z - screen_position.x);
-        let half_screen = Vector2::new(window_size.x as f32 / 2.0, window_size.y as f32 / 2.0);
+        let (character_layout, heigth) = font_loader.get(text, color, font_size, screen_clip.right - screen_position.left);
+        let half_screen = window_size / 2.0;
 
         let (layout, set, set_id) = allocate_descriptor_set(&self.pipeline, &self.memory_allocator, 0, [
             WriteDescriptorSet::image_view_sampler(0, texture, self.nearest_sampler.clone()),
@@ -109,15 +109,15 @@ impl TextRenderer {
             .unwrap();
 
         character_layout.iter().for_each(|(texture_coordinates, position, color)| {
-            let screen_position = Vector2::new(
-                (screen_position.x + position.min.x as f32) / half_screen.x,
-                (screen_position.y + position.min.y as f32) / half_screen.y,
-            );
+            let screen_position = ScreenPosition {
+                left: screen_position.left + position.min.x as f32,
+                top: screen_position.top + position.min.y as f32,
+            } / half_screen;
 
-            let screen_size = Vector2::new(
-                position.width() as f32 / half_screen.x,
-                position.height() as f32 / half_screen.y,
-            );
+            let screen_size = ScreenSize {
+                width: position.width() as f32,
+                height: position.height() as f32,
+            } / half_screen;
 
             let texture_position = texture_coordinates.min;
             let texture_size = texture_coordinates.max - texture_coordinates.min; // TODO: use absolute instead
@@ -125,10 +125,10 @@ impl TextRenderer {
             let constants = Constants {
                 screen_position: screen_position.into(),
                 screen_size: screen_size.into(),
-                clip_size: clip_size.into(),
+                screen_clip: screen_clip.into(),
                 texture_position: [texture_position.x, texture_position.y],
                 texture_size: [texture_size.x, texture_size.y],
-                color: [color.red_f32(), color.green_f32(), color.blue_f32(), color.alpha_f32()],
+                color: (*color).into(),
             };
 
             render_target
diff --git a/src/graphics/renderers/interface/text/vertex_shader.glsl b/src/graphics/renderers/interface/text/vertex_shader.glsl
index 9aea46ed..1e8a4fd0 100644
--- a/src/graphics/renderers/interface/text/vertex_shader.glsl
+++ b/src/graphics/renderers/interface/text/vertex_shader.glsl
@@ -5,7 +5,7 @@ layout(location = 0) out vec2 texture_coordinates;
 layout(push_constant) uniform Constants {
     vec2 screen_position;
     vec2 screen_size;
-    vec4 clip_size;
+    vec4 screen_clip;
     vec2 texture_position;
     vec2 texture_size;
     vec4 color;
diff --git a/src/graphics/renderers/mod.rs b/src/graphics/renderers/mod.rs
index 4e79d99d..721bc7ec 100644
--- a/src/graphics/renderers/mod.rs
+++ b/src/graphics/renderers/mod.rs
@@ -42,7 +42,7 @@ mod swapchain;
 use std::marker::{ConstParamTy, PhantomData};
 use std::sync::Arc;
 
-use cgmath::{Matrix4, Vector2, Vector3, Vector4};
+use cgmath::{Matrix4, Vector2, Vector3};
 use option_ext::OptionExt;
 use procedural::profile;
 use vulkano::buffer::{Buffer, BufferUsage, Subbuffer};
@@ -76,6 +76,7 @@ use super::{Color, MemoryAllocator, ModelVertex};
 #[cfg(feature = "debug")]
 use crate::debug::*;
 use crate::graphics::Camera;
+use crate::interface::{ScreenClip, ScreenPosition, ScreenSize};
 use crate::network::EntityId;
 #[cfg(feature = "debug")]
 use crate::world::MarkerIdentifier;
@@ -177,9 +178,9 @@ pub trait SpriteRenderer {
         &self,
         render_target: &mut <Self as Renderer>::Target,
         texture: Arc<ImageView>,
-        position: Vector2<f32>,
-        size: Vector2<f32>,
-        clip_size: Vector4<f32>,
+        position: ScreenPosition,
+        size: ScreenSize,
+        screen_clip: ScreenClip,
         color: Color,
         smooth: bool,
     ) where
diff --git a/src/graphics/renderers/picker/entity/mod.rs b/src/graphics/renderers/picker/entity/mod.rs
index 3244b9f1..e7a0dfa5 100644
--- a/src/graphics/renderers/picker/entity/mod.rs
+++ b/src/graphics/renderers/picker/entity/mod.rs
@@ -124,8 +124,8 @@ impl EntityRenderer {
 
         let constants = Constants {
             world: world_matrix.into(),
-            texture_position: [texture_position.x, texture_position.y],
-            texture_size: [texture_size.x, texture_size.y],
+            texture_position: texture_position.into(),
+            texture_size: texture_size.into(),
             identifier: picker_target.into(),
             mirror: mirror as u32,
         };
diff --git a/src/graphics/renderers/picker/marker/mod.rs b/src/graphics/renderers/picker/marker/mod.rs
index d972e357..8f4d85ec 100644
--- a/src/graphics/renderers/picker/marker/mod.rs
+++ b/src/graphics/renderers/picker/marker/mod.rs
@@ -3,7 +3,6 @@ fragment_shader!("src/graphics/renderers/picker/marker/fragment_shader.glsl");
 
 use std::sync::Arc;
 
-use cgmath::Vector2;
 use procedural::profile;
 use vulkano::device::{Device, DeviceOwned};
 use vulkano::pipeline::graphics::viewport::Viewport;
@@ -15,6 +14,7 @@ use self::vertex_shader::Constants;
 use super::PickerSubrenderer;
 use crate::graphics::renderers::pipeline::PipelineBuilder;
 use crate::graphics::*;
+use crate::interface::{ScreenPosition, ScreenSize};
 use crate::world::MarkerIdentifier;
 
 pub struct MarkerRenderer {
@@ -67,8 +67,8 @@ impl MarkerRenderer {
     pub fn render(
         &self,
         render_target: &mut <PickerRenderer as Renderer>::Target,
-        screen_position: Vector2<f32>,
-        screen_size: Vector2<f32>,
+        screen_position: ScreenPosition,
+        screen_size: ScreenSize,
         marker_identifier: MarkerIdentifier,
     ) {
         if render_target.bind_subrenderer(PickerSubrenderer::Marker) {
diff --git a/src/graphics/renderers/shadow/entity/mod.rs b/src/graphics/renderers/shadow/entity/mod.rs
index 58838723..bae7b3aa 100644
--- a/src/graphics/renderers/shadow/entity/mod.rs
+++ b/src/graphics/renderers/shadow/entity/mod.rs
@@ -118,8 +118,8 @@ impl EntityRenderer {
 
         let constants = Constants {
             world: world_matrix.into(),
-            texture_position: [texture_position.x, texture_position.y],
-            texture_size: [texture_size.x, texture_size.y],
+            texture_position: texture_position.into(),
+            texture_size: texture_size.into(),
             depth_offset,
             curvature,
             mirror: mirror as u32,
diff --git a/src/graphics/renderers/swapchain.rs b/src/graphics/renderers/swapchain.rs
index a798499e..3519fa86 100644
--- a/src/graphics/renderers/swapchain.rs
+++ b/src/graphics/renderers/swapchain.rs
@@ -14,6 +14,7 @@ use winit::window::Window;
 
 #[cfg(feature = "debug")]
 use crate::debug::*;
+use crate::interface::ScreenSize;
 
 #[derive(Debug, Clone, Copy)]
 pub struct PresentModeInfo {
@@ -206,7 +207,10 @@ impl SwapchainHolder {
         self.window_size
     }
 
-    pub fn window_size_f32(&self) -> Vector2<f32> {
-        self.window_size.map(|component| component as f32).into()
+    pub fn window_screen_size(&self) -> ScreenSize {
+        ScreenSize {
+            width: self.window_size[0] as f32,
+            height: self.window_size[1] as f32,
+        }
     }
 }
diff --git a/src/input/mod.rs b/src/input/mod.rs
index cf0e9699..12335660 100644
--- a/src/input/mod.rs
+++ b/src/input/mod.rs
@@ -16,7 +16,7 @@ pub use self::mode::{Grabbed, MouseInputMode};
 #[cfg(feature = "debug")]
 use crate::graphics::RenderSettings;
 use crate::graphics::{PickerRenderTarget, PickerTarget};
-use crate::interface::{ClickAction, ElementCell, Focus, Interface, MouseCursorState, WeakElementCell};
+use crate::interface::{ClickAction, ElementCell, Focus, Interface, MouseCursorState, ScreenPosition, ScreenSize, WeakElementCell};
 use crate::network::ClientTick;
 
 const MOUSE_SCOLL_MULTIPLIER: f32 = 30.0;
@@ -102,9 +102,9 @@ impl FocusState {
 }
 
 pub struct InputSystem {
-    previous_mouse_position: Vector2<f32>,
-    new_mouse_position: Vector2<f32>,
-    mouse_delta: Vector2<f32>,
+    previous_mouse_position: ScreenPosition,
+    new_mouse_position: ScreenPosition,
+    mouse_delta: ScreenSize,
     previous_scroll_position: f32,
     new_scroll_position: f32,
     scroll_delta: f32,
@@ -117,9 +117,9 @@ pub struct InputSystem {
 
 impl InputSystem {
     pub fn new() -> Self {
-        let previous_mouse_position = Vector2::new(0.0, 0.0);
-        let new_mouse_position = Vector2::new(0.0, 0.0);
-        let mouse_delta = Vector2::new(0.0, 0.0);
+        let previous_mouse_position = ScreenPosition::default();
+        let new_mouse_position = ScreenPosition::default();
+        let mouse_delta = ScreenSize::default();
 
         let previous_scroll_position = 0.0;
         let new_scroll_position = 0.0;
@@ -155,7 +155,10 @@ impl InputSystem {
     }
 
     pub fn update_mouse_position(&mut self, position: PhysicalPosition<f64>) {
-        self.new_mouse_position = Vector2::new(position.x as f32, position.y as f32);
+        self.new_mouse_position = ScreenPosition {
+            left: position.x as f32,
+            top: position.y as f32,
+        };
     }
 
     pub fn update_mouse_buttons(&mut self, button: MouseButton, state: ElementState) {
@@ -361,7 +364,7 @@ impl InputSystem {
         if self.right_mouse_button.down()
             && !self.right_mouse_button.pressed()
             && self.mouse_input_mode.is_none()
-            && self.mouse_delta.x != 0.0
+            && self.mouse_delta.width != 0.0
             && !lock_actions
         {
             self.mouse_input_mode = MouseInputMode::RotateCamera;
@@ -369,24 +372,24 @@ impl InputSystem {
 
         match &self.mouse_input_mode {
             MouseInputMode::DragElement((element, window_index)) => {
-                if self.mouse_delta != Vector2::new(0.0, 0.0) {
-                    interface.drag_element(element, *window_index, self.mouse_delta);
+                if self.mouse_delta != ScreenSize::default() {
+                    interface.drag_element(element, *window_index, ScreenPosition::from_size(self.mouse_delta));
                 }
                 interface.set_mouse_cursor_state(MouseCursorState::Grab, client_tick);
             }
             MouseInputMode::MoveInterface(identifier) => {
-                if self.mouse_delta != Vector2::new(0.0, 0.0) {
-                    interface.move_window(*identifier, self.mouse_delta);
+                if self.mouse_delta != ScreenSize::default() {
+                    interface.move_window(*identifier, ScreenPosition::from_size(self.mouse_delta));
                 }
                 interface.set_mouse_cursor_state(MouseCursorState::Grab, client_tick);
             }
             MouseInputMode::ResizeInterface(identifier) => {
-                if self.mouse_delta != Vector2::new(0.0, 0.0) {
+                if self.mouse_delta != ScreenSize::default() {
                     interface.resize_window(*identifier, self.mouse_delta);
                 }
             }
             MouseInputMode::RotateCamera => {
-                events.push(UserEvent::CameraRotate(self.mouse_delta.x));
+                events.push(UserEvent::CameraRotate(self.mouse_delta.width));
                 interface.set_mouse_cursor_state(MouseCursorState::RotateCamera, client_tick);
             }
             MouseInputMode::ClickInterface => interface.set_mouse_cursor_state(MouseCursorState::Click, client_tick),
@@ -573,7 +576,10 @@ impl InputSystem {
                 && self.mouse_input_mode.is_none()
                 && render_settings.use_debug_camera
             {
-                events.push(UserEvent::CameraLookAround(-self.mouse_delta));
+                events.push(UserEvent::CameraLookAround(-Vector2::new(
+                    self.mouse_delta.width,
+                    self.mouse_delta.height,
+                )));
             }
 
             #[cfg(feature = "debug")]
@@ -607,7 +613,7 @@ impl InputSystem {
                 fence.wait(None).unwrap();
             }
 
-            let sample_index = self.new_mouse_position.x as usize + self.new_mouse_position.y as usize * window_size.x;
+            let sample_index = self.new_mouse_position.left as usize + self.new_mouse_position.top as usize * window_size.x;
             let lock = picker_target.buffer.read().unwrap();
 
             if sample_index < lock.len() {
@@ -680,7 +686,7 @@ impl InputSystem {
         (events, hovered_element, focused_element, mouse_target)
     }
 
-    pub fn get_mouse_position(&self) -> Vector2<f32> {
+    pub fn get_mouse_position(&self) -> ScreenPosition {
         self.new_mouse_position
     }
 
diff --git a/src/interface/cursor/mod.rs b/src/interface/cursor/mod.rs
index 77011746..46f223e7 100644
--- a/src/interface/cursor/mod.rs
+++ b/src/interface/cursor/mod.rs
@@ -1,8 +1,6 @@
 use std::sync::Arc;
 
-use cgmath::{Array, Vector2, Vector4, Zero};
-
-use super::InterfaceSettings;
+use super::{InterfaceSettings, ScreenClip, ScreenPosition, ScreenSize};
 use crate::graphics::{Color, DeferredRenderer, Renderer, SpriteRenderer};
 use crate::input::Grabbed;
 use crate::loaders::{ActionLoader, Actions, AnimationState, GameFileLoader, Sprite, SpriteLoader};
@@ -70,7 +68,7 @@ impl MouseCursor {
         &self,
         render_target: &mut <DeferredRenderer as Renderer>::Target,
         renderer: &DeferredRenderer,
-        mouse_position: Vector2<f32>,
+        mouse_position: ScreenPosition,
         grabbed: Option<Grabbed>,
         color: Color,
         interface_settings: &InterfaceSettings,
@@ -80,9 +78,9 @@ impl MouseCursor {
                 Grabbed::Texture(texture) => renderer.render_sprite(
                     render_target,
                     texture,
-                    mouse_position - Vector2::from_value(15.0 * *interface_settings.scaling),
-                    Vector2::from_value(30.0 * *interface_settings.scaling),
-                    Vector4::zero(),
+                    mouse_position - ScreenSize::uniform(15.0 * *interface_settings.scaling),
+                    ScreenSize::uniform(30.0 * *interface_settings.scaling),
+                    ScreenClip::default(),
                     Color::monochrome(255),
                     false,
                 ),
diff --git a/src/interface/elements/base.rs b/src/interface/elements/base.rs
index 6a1610c8..7cd34598 100644
--- a/src/interface/elements/base.rs
+++ b/src/interface/elements/base.rs
@@ -2,7 +2,7 @@ use std::cell::{Cell, RefCell};
 use std::rc::{Rc, Weak};
 use std::sync::Arc;
 
-use cgmath::{Vector2, Vector4, Zero};
+use cgmath::Vector2;
 use vulkano::image::view::ImageView;
 
 use crate::graphics::{Color, InterfaceRenderer, Renderer, SpriteRenderer};
@@ -30,13 +30,13 @@ pub struct ElementRenderer<'a> {
     pub render_target: &'a mut <InterfaceRenderer as Renderer>::Target,
     pub renderer: &'a InterfaceRenderer,
     pub interface_settings: &'a InterfaceSettings,
-    pub position: Position,
-    pub size: Size,
-    pub clip_size: ClipSize,
+    pub position: ScreenPosition,
+    pub size: ScreenSize,
+    pub screen_clip: ScreenClip,
 }
 
 impl<'a> ElementRenderer<'a> {
-    pub fn get_position(&self) -> Position {
+    pub fn get_position(&self) -> ScreenPosition {
         self.position
     }
 
@@ -46,71 +46,71 @@ impl<'a> ElementRenderer<'a> {
     }
 
     pub fn set_scroll(&mut self, scroll: f32) {
-        self.position.y -= scroll;
+        self.position.top -= scroll;
     }
 
-    pub fn render_background(&mut self, border_radius: Vector4<f32>, color: Color) {
+    pub fn render_background(&mut self, corner_radius: CornerRadius, color: Color) {
         self.renderer.render_rectangle(
             self.render_target,
             self.position,
             self.size,
-            self.clip_size,
-            border_radius * *self.interface_settings.scaling,
+            self.screen_clip,
+            corner_radius * *self.interface_settings.scaling,
             color,
         );
     }
 
-    pub fn render_rectangle(&mut self, position: Position, size: Size, border_radius: Vector4<f32>, color: Color) {
+    pub fn render_rectangle(&mut self, position: ScreenPosition, size: ScreenSize, corner_radius: CornerRadius, color: Color) {
         self.renderer.render_rectangle(
             self.render_target,
             self.position + position,
             size,
-            self.clip_size,
-            border_radius * *self.interface_settings.scaling,
+            self.screen_clip,
+            corner_radius * *self.interface_settings.scaling,
             color,
         );
     }
 
-    pub fn render_text(&mut self, text: &str, offset: Position, foreground_color: Color, font_size: f32) -> f32 {
+    pub fn render_text(&mut self, text: &str, offset: ScreenPosition, foreground_color: Color, font_size: f32) -> f32 {
         self.renderer.render_text(
             self.render_target,
             text,
             self.position + offset * *self.interface_settings.scaling,
-            self.clip_size,
+            self.screen_clip,
             foreground_color,
             font_size * *self.interface_settings.scaling,
         )
     }
 
-    pub fn render_checkbox(&mut self, offset: Position, size: Size, color: Color, checked: bool) {
+    pub fn render_checkbox(&mut self, offset: ScreenPosition, size: ScreenSize, color: Color, checked: bool) {
         self.renderer.render_checkbox(
             self.render_target,
             self.position + offset * *self.interface_settings.scaling,
             size * *self.interface_settings.scaling,
-            self.clip_size,
+            self.screen_clip,
             color,
             checked,
         );
     }
 
-    pub fn render_expand_arrow(&mut self, offset: Position, size: Size, color: Color, expanded: bool) {
+    pub fn render_expand_arrow(&mut self, offset: ScreenPosition, size: ScreenSize, color: Color, expanded: bool) {
         self.renderer.render_expand_arrow(
             self.render_target,
             self.position + offset * *self.interface_settings.scaling,
             size * *self.interface_settings.scaling,
-            self.clip_size,
+            self.screen_clip,
             color,
             expanded,
         );
     }
 
-    pub fn render_sprite(&mut self, texture: Arc<ImageView>, offset: Position, size: Size, color: Color) {
+    pub fn render_sprite(&mut self, texture: Arc<ImageView>, offset: ScreenPosition, size: ScreenSize, color: Color) {
         self.renderer.render_sprite(
             self.render_target,
             texture,
             self.position + offset * *self.interface_settings.scaling,
             size * *self.interface_settings.scaling,
-            self.clip_size,
+            self.screen_clip,
             color,
             false,
         );
@@ -134,7 +134,7 @@ impl<'a> ElementRenderer<'a> {
             interface_settings,
             theme,
             self.position,
-            self.clip_size,
+            self.screen_clip,
             hovered_element,
             focused_element,
             mouse_mode,
@@ -143,24 +143,13 @@ impl<'a> ElementRenderer<'a> {
     }
 }
 
+#[derive(Default)]
 pub struct ElementState {
-    pub cached_size: Size,
-    pub cached_position: Position,
+    pub cached_size: ScreenSize,
+    pub cached_position: ScreenPosition,
     pub self_element: Option<WeakElementCell>,
     pub parent_element: Option<WeakElementCell>,
-    pub mouse_position: Cell<Position>,
-}
-
-impl Default for ElementState {
-    fn default() -> Self {
-        Self {
-            cached_size: Size::zero(),
-            cached_position: Position::zero(),
-            self_element: None,
-            parent_element: None,
-            mouse_position: Cell::new(Position::zero()),
-        }
-    }
+    pub mouse_position: Cell<ScreenPosition>,
 }
 
 impl ElementState {
@@ -175,13 +164,13 @@ impl ElementState {
         self.cached_position = position;
     }
 
-    pub fn hovered_element(&self, mouse_position: Position) -> HoverInformation {
-        let absolute_position = mouse_position - self.cached_position;
+    pub fn hovered_element(&self, mouse_position: ScreenPosition) -> HoverInformation {
+        let absolute_position = ScreenPosition::from_size(mouse_position - self.cached_position);
 
-        if absolute_position.x >= 0.0
-            && absolute_position.y >= 0.0
-            && absolute_position.x <= self.cached_size.x
-            && absolute_position.y <= self.cached_size.y
+        if absolute_position.left >= 0.0
+            && absolute_position.top >= 0.0
+            && absolute_position.left <= self.cached_size.width
+            && absolute_position.top <= self.cached_size.height
         {
             self.mouse_position.replace(absolute_position);
             return HoverInformation::Hovered;
@@ -195,18 +184,18 @@ impl ElementState {
         render_target: &'a mut <InterfaceRenderer as Renderer>::Target,
         renderer: &'a InterfaceRenderer,
         interface_settings: &'a InterfaceSettings,
-        parent_position: Position,
-        clip_size: ClipSize,
+        parent_position: ScreenPosition,
+        screen_clip: ScreenClip,
     ) -> ElementRenderer<'a> {
         let position = parent_position + self.cached_position;
         let size = self.cached_size;
 
-        let clip_size = Vector4::new(
-            clip_size.x.max(position.x),
-            clip_size.y.max(position.y),
-            clip_size.z.min(position.x + self.cached_size.x),
-            clip_size.w.min(position.y + self.cached_size.y),
-        );
+        let screen_clip = ScreenClip {
+            left: screen_clip.left.max(position.left),
+            top: screen_clip.top.max(position.top),
+            right: screen_clip.right.min(position.left + self.cached_size.width),
+            bottom: screen_clip.bottom.min(position.top + self.cached_size.height),
+        };
 
         ElementRenderer {
             render_target,
@@ -214,7 +203,7 @@ impl ElementState {
             interface_settings,
             position,
             size,
-            clip_size,
+            screen_clip,
         }
     }
 }
@@ -301,7 +290,7 @@ pub trait Element {
         matches!(element, Some(reference) if std::ptr::eq(reference as *const _ as *const (), self as *const _ as *const ()))
     }
 
-    fn hovered_element(&self, _mouse_position: Vector2<f32>, _mouse_mode: &MouseInputMode) -> HoverInformation {
+    fn hovered_element(&self, _mouse_position: ScreenPosition, _mouse_mode: &MouseInputMode) -> HoverInformation {
         HoverInformation::Missed
     }
 
@@ -313,7 +302,7 @@ pub trait Element {
         Vec::new()
     }
 
-    fn drag(&mut self, _mouse_delta: Position) -> Option<ChangeEvent> {
+    fn drag(&mut self, _mouse_delta: ScreenPosition) -> Option<ChangeEvent> {
         None
     }
 
@@ -346,8 +335,8 @@ pub trait Element {
         state_provider: &StateProvider,
         interface_settings: &InterfaceSettings,
         theme: &InterfaceTheme,
-        parent_position: Position,
-        clip_size: ClipSize,
+        parent_position: ScreenPosition,
+        screen_clip: ScreenClip,
         hovered_element: Option<&dyn Element>,
         focused_element: Option<&dyn Element>,
         mouse_mode: &MouseInputMode,
diff --git a/src/interface/elements/buttons/close.rs b/src/interface/elements/buttons/close.rs
index 7f2180e7..745091b5 100644
--- a/src/interface/elements/buttons/close.rs
+++ b/src/interface/elements/buttons/close.rs
@@ -26,7 +26,7 @@ impl Element for CloseButton {
         false
     }
 
-    fn hovered_element(&self, mouse_position: Position, mouse_mode: &MouseInputMode) -> HoverInformation {
+    fn hovered_element(&self, mouse_position: ScreenPosition, mouse_mode: &MouseInputMode) -> HoverInformation {
         match mouse_mode {
             MouseInputMode::None => self.state.hovered_element(mouse_position),
             _ => HoverInformation::Missed,
@@ -44,8 +44,8 @@ impl Element for CloseButton {
         _state_provider: &StateProvider,
         interface_settings: &InterfaceSettings,
         theme: &InterfaceTheme,
-        parent_position: Position,
-        clip_size: ClipSize,
+        parent_position: ScreenPosition,
+        screen_clip: ScreenClip,
         hovered_element: Option<&dyn Element>,
         focused_element: Option<&dyn Element>,
         _mouse_mode: &MouseInputMode,
@@ -53,18 +53,23 @@ impl Element for CloseButton {
     ) {
         let mut renderer = self
             .state
-            .element_renderer(render_target, renderer, interface_settings, parent_position, clip_size);
+            .element_renderer(render_target, renderer, interface_settings, parent_position, screen_clip);
 
         let background_color = match self.is_element_self(hovered_element) || self.is_element_self(focused_element) {
             true => *theme.close_button.hovered_background_color,
             false => *theme.close_button.background_color,
         };
 
-        renderer.render_background(*theme.close_button.border_radius, background_color);
+        renderer.render_background((*theme.close_button.corner_radius).into(), background_color);
+
+        let text_position = ScreenPosition {
+            left: theme.close_button.text_offset.x,
+            top: theme.close_button.text_offset.y,
+        };
 
         renderer.render_text(
             "X",
-            *theme.close_button.text_offset,
+            text_position,
             *theme.close_button.foreground_color,
             *theme.close_button.font_size,
         );
diff --git a/src/interface/elements/buttons/default.rs b/src/interface/elements/buttons/default.rs
index 3272ed17..dae6ec06 100644
--- a/src/interface/elements/buttons/default.rs
+++ b/src/interface/elements/buttons/default.rs
@@ -101,7 +101,7 @@ impl<T: AsRef<str> + 'static, E: ElementEvent> Element for Button<T, E> {
         self.state.resolve(placement_resolver, &size_constraint);
     }
 
-    fn hovered_element(&self, mouse_position: Position, mouse_mode: &MouseInputMode) -> HoverInformation {
+    fn hovered_element(&self, mouse_position: ScreenPosition, mouse_mode: &MouseInputMode) -> HoverInformation {
         match mouse_mode {
             MouseInputMode::None => self.state.hovered_element(mouse_position),
             _ => HoverInformation::Missed,
@@ -123,8 +123,8 @@ impl<T: AsRef<str> + 'static, E: ElementEvent> Element for Button<T, E> {
         _state_provider: &StateProvider,
         interface_settings: &InterfaceSettings,
         theme: &InterfaceTheme,
-        parent_position: Position,
-        clip_size: ClipSize,
+        parent_position: ScreenPosition,
+        screen_clip: ScreenClip,
         hovered_element: Option<&dyn Element>,
         focused_element: Option<&dyn Element>,
         _mouse_mode: &MouseInputMode,
@@ -132,7 +132,7 @@ impl<T: AsRef<str> + 'static, E: ElementEvent> Element for Button<T, E> {
     ) {
         let mut renderer = self
             .state
-            .element_renderer(render_target, renderer, interface_settings, parent_position, clip_size);
+            .element_renderer(render_target, renderer, interface_settings, parent_position, screen_clip);
 
         let disabled = self.is_disabled();
         let background_color = match self.is_element_self(hovered_element) || self.is_element_self(focused_element) {
@@ -142,7 +142,7 @@ impl<T: AsRef<str> + 'static, E: ElementEvent> Element for Button<T, E> {
             false => *theme.button.background_color,
         };
 
-        renderer.render_background(*theme.button.border_radius, background_color);
+        renderer.render_background((*theme.button.corner_radius).into(), background_color);
 
         if let Some(text) = &self.text {
             let foreground_color = if disabled {
@@ -154,12 +154,12 @@ impl<T: AsRef<str> + 'static, E: ElementEvent> Element for Button<T, E> {
                     .unwrap_or(*theme.button.foreground_color)
             };
 
-            renderer.render_text(
-                text.as_ref(),
-                *theme.button.text_offset,
-                foreground_color,
-                *theme.button.font_size,
-            );
+            let text_position = ScreenPosition {
+                left: theme.button.text_offset.x,
+                top: theme.button.text_offset.y,
+            };
+
+            renderer.render_text(text.as_ref(), text_position, foreground_color, *theme.button.font_size);
         }
     }
 }
diff --git a/src/interface/elements/buttons/drag.rs b/src/interface/elements/buttons/drag.rs
index 6ac02aba..36616292 100644
--- a/src/interface/elements/buttons/drag.rs
+++ b/src/interface/elements/buttons/drag.rs
@@ -31,7 +31,7 @@ impl Element for DragButton {
         false
     }
 
-    fn hovered_element(&self, mouse_position: Position, mouse_mode: &MouseInputMode) -> HoverInformation {
+    fn hovered_element(&self, mouse_position: ScreenPosition, mouse_mode: &MouseInputMode) -> HoverInformation {
         match mouse_mode {
             MouseInputMode::None => self.state.hovered_element(mouse_position),
             MouseInputMode::DragElement((element, _)) if self.is_element_self(Some(&*element.borrow())) => HoverInformation::Hovered,
@@ -50,8 +50,8 @@ impl Element for DragButton {
         _state_provider: &StateProvider,
         interface_settings: &InterfaceSettings,
         theme: &InterfaceTheme,
-        parent_position: Position,
-        clip_size: ClipSize,
+        parent_position: ScreenPosition,
+        screen_clip: ScreenClip,
         hovered_element: Option<&dyn Element>,
         _focused_element: Option<&dyn Element>,
         _mouse_mode: &MouseInputMode,
@@ -59,15 +59,20 @@ impl Element for DragButton {
     ) {
         let mut renderer = self
             .state
-            .element_renderer(render_target, renderer, interface_settings, parent_position, clip_size);
+            .element_renderer(render_target, renderer, interface_settings, parent_position, screen_clip);
 
         if self.is_element_self(hovered_element) {
-            renderer.render_background(*theme.window.title_border_radius, *theme.window.title_background_color);
+            renderer.render_background((*theme.window.title_corner_radius).into(), *theme.window.title_background_color);
         }
 
+        let text_position = ScreenPosition {
+            left: theme.window.text_offset.x,
+            top: theme.window.text_offset.y,
+        };
+
         renderer.render_text(
             &self.window_title,
-            *theme.window.text_offset,
+            text_position,
             *theme.window.foreground_color,
             *theme.window.font_size,
         );
diff --git a/src/interface/elements/buttons/state.rs b/src/interface/elements/buttons/state.rs
index 3509f9e7..d88e0a74 100644
--- a/src/interface/elements/buttons/state.rs
+++ b/src/interface/elements/buttons/state.rs
@@ -91,7 +91,7 @@ where
         self.state.resolve(placement_resolver, &size_constraint);
     }
 
-    fn hovered_element(&self, mouse_position: Position, mouse_mode: &MouseInputMode) -> HoverInformation {
+    fn hovered_element(&self, mouse_position: ScreenPosition, mouse_mode: &MouseInputMode) -> HoverInformation {
         match mouse_mode {
             MouseInputMode::None => self.state.hovered_element(mouse_position),
             _ => HoverInformation::Missed,
@@ -109,8 +109,8 @@ where
         state_provider: &StateProvider,
         interface_settings: &InterfaceSettings,
         theme: &InterfaceTheme,
-        parent_position: Position,
-        clip_size: ClipSize,
+        parent_position: ScreenPosition,
+        screen_clip: ScreenClip,
         hovered_element: Option<&dyn Element>,
         focused_element: Option<&dyn Element>,
         _mouse_mode: &MouseInputMode,
@@ -118,7 +118,7 @@ where
     ) {
         let mut renderer = self
             .state
-            .element_renderer(render_target, renderer, interface_settings, parent_position, clip_size);
+            .element_renderer(render_target, renderer, interface_settings, parent_position, screen_clip);
 
         let highlighted = self.is_element_self(hovered_element) || self.is_element_self(focused_element);
 
@@ -128,7 +128,7 @@ where
                 false => *theme.button.background_color,
             };
 
-            renderer.render_background(*theme.button.border_radius, background_color);
+            renderer.render_background((*theme.button.corner_radius).into(), background_color);
         }
 
         let foreground_color = match self.transparent_background && highlighted {
@@ -136,20 +136,30 @@ where
             false => *theme.button.foreground_color,
         };
 
+        let box_position = ScreenPosition {
+            left: theme.button.icon_offset.x,
+            top: theme.button.icon_offset.y,
+        };
+
+        let box_size = ScreenSize {
+            width: theme.button.icon_size.x,
+            height: theme.button.icon_size.y,
+        };
+
         renderer.render_checkbox(
-            *theme.button.icon_offset,
-            *theme.button.icon_size,
+            box_position,
+            box_size,
             foreground_color,
             (self.selector.as_ref().unwrap())(state_provider),
         );
 
         if let Some(text) = &self.text {
-            renderer.render_text(
-                text.as_ref(),
-                *theme.button.icon_text_offset,
-                foreground_color,
-                *theme.button.font_size,
-            );
+            let text_position = ScreenPosition {
+                left: theme.button.icon_text_offset.x,
+                top: theme.button.icon_text_offset.y,
+            };
+
+            renderer.render_text(text.as_ref(), text_position, foreground_color, *theme.button.font_size);
         }
     }
 }
diff --git a/src/interface/elements/containers/character.rs b/src/interface/elements/containers/character.rs
index c181e739..21e8aae7 100644
--- a/src/interface/elements/containers/character.rs
+++ b/src/interface/elements/containers/character.rs
@@ -1,7 +1,6 @@
 use std::cell::RefCell;
 use std::rc::Weak;
 
-use cgmath::Array;
 use procedural::*;
 
 use crate::graphics::{Color, InterfaceRenderer, Renderer};
@@ -112,7 +111,7 @@ impl Element for CharacterPreview {
             interface_settings,
             theme,
             size_constraint,
-            Vector2::from_value(4.0),
+            ScreenSize::uniform(4.0),
         );
     }
 
@@ -154,7 +153,7 @@ impl Element for CharacterPreview {
         vec![ClickAction::Event(event)]
     }
 
-    fn hovered_element(&self, mouse_position: Position, mouse_mode: &MouseInputMode) -> HoverInformation {
+    fn hovered_element(&self, mouse_position: ScreenPosition, mouse_mode: &MouseInputMode) -> HoverInformation {
         match mouse_mode {
             MouseInputMode::None => self.state.hovered_element(mouse_position, mouse_mode, true),
             _ => HoverInformation::Missed,
@@ -168,8 +167,8 @@ impl Element for CharacterPreview {
         state_provider: &StateProvider,
         interface_settings: &InterfaceSettings,
         theme: &InterfaceTheme,
-        parent_position: Position,
-        clip_size: ClipSize,
+        parent_position: ScreenPosition,
+        screen_clip: ScreenClip,
         hovered_element: Option<&dyn Element>,
         focused_element: Option<&dyn Element>,
         mouse_mode: &MouseInputMode,
@@ -178,14 +177,14 @@ impl Element for CharacterPreview {
         let mut renderer = self
             .state
             .state
-            .element_renderer(render_target, renderer, interface_settings, parent_position, clip_size);
+            .element_renderer(render_target, renderer, interface_settings, parent_position, screen_clip);
 
         let background_color = match self.is_element_self(hovered_element) || self.is_element_self(focused_element) {
             true => *theme.button.hovered_background_color,
             false => *theme.button.background_color,
         };
 
-        renderer.render_background(*theme.button.border_radius, background_color);
+        renderer.render_background((*theme.button.corner_radius).into(), background_color);
 
         self.state.render(
             &mut renderer,
diff --git a/src/interface/elements/containers/default.rs b/src/interface/elements/containers/default.rs
index 9aafe595..fa19698d 100644
--- a/src/interface/elements/containers/default.rs
+++ b/src/interface/elements/containers/default.rs
@@ -1,6 +1,5 @@
 use std::rc::Weak;
 
-use cgmath::Zero;
 use procedural::*;
 
 use crate::graphics::{InterfaceRenderer, Renderer};
@@ -9,7 +8,7 @@ use crate::interface::{Element, *};
 
 pub struct Container {
     size_constraint: Option<SizeConstraint>,
-    border_size: Option<Vector2<f32>>,
+    border_size: Option<ScreenSize>,
     state: ContainerState,
 }
 
@@ -56,7 +55,7 @@ impl Element for Container {
 
     fn resolve(&mut self, placement_resolver: &mut PlacementResolver, interface_settings: &InterfaceSettings, theme: &InterfaceTheme) {
         let size_constraint = self.size_constraint.as_ref().unwrap_or(&constraint!(100%, ?));
-        let border = self.border_size.unwrap_or_else(Vector2::zero);
+        let border = self.border_size.unwrap_or_default();
 
         self.state
             .resolve(placement_resolver, interface_settings, theme, size_constraint, border);
@@ -66,7 +65,7 @@ impl Element for Container {
         self.state.update()
     }
 
-    fn hovered_element(&self, mouse_position: Position, mouse_mode: &MouseInputMode) -> HoverInformation {
+    fn hovered_element(&self, mouse_position: ScreenPosition, mouse_mode: &MouseInputMode) -> HoverInformation {
         self.state.hovered_element(mouse_position, mouse_mode, false)
     }
 
@@ -77,8 +76,8 @@ impl Element for Container {
         state_provider: &StateProvider,
         interface_settings: &InterfaceSettings,
         theme: &InterfaceTheme,
-        parent_position: Position,
-        clip_size: ClipSize,
+        parent_position: ScreenPosition,
+        screen_clip: ScreenClip,
         hovered_element: Option<&dyn Element>,
         focused_element: Option<&dyn Element>,
         mouse_mode: &MouseInputMode,
@@ -87,7 +86,7 @@ impl Element for Container {
         let mut renderer = self
             .state
             .state
-            .element_renderer(render_target, renderer, interface_settings, parent_position, clip_size);
+            .element_renderer(render_target, renderer, interface_settings, parent_position, screen_clip);
 
         self.state.render(
             &mut renderer,
diff --git a/src/interface/elements/containers/dialog.rs b/src/interface/elements/containers/dialog.rs
index 19b82ed9..bcf2d81b 100644
--- a/src/interface/elements/containers/dialog.rs
+++ b/src/interface/elements/containers/dialog.rs
@@ -1,4 +1,3 @@
-use cgmath::Array;
 use procedural::*;
 
 use crate::graphics::{Color, InterfaceRenderer, Renderer};
@@ -77,7 +76,7 @@ impl Element for DialogContainer {
             interface_settings,
             theme,
             size_constraint,
-            Vector2::from_value(3.0),
+            ScreenSize::uniform(3.0),
         );
     }
 
@@ -93,7 +92,7 @@ impl Element for DialogContainer {
         None
     }
 
-    fn hovered_element(&self, mouse_position: Position, mouse_mode: &MouseInputMode) -> HoverInformation {
+    fn hovered_element(&self, mouse_position: ScreenPosition, mouse_mode: &MouseInputMode) -> HoverInformation {
         self.state.hovered_element(mouse_position, mouse_mode, false)
     }
 
@@ -104,8 +103,8 @@ impl Element for DialogContainer {
         state_provider: &StateProvider,
         interface_settings: &InterfaceSettings,
         theme: &InterfaceTheme,
-        parent_position: Position,
-        clip_size: ClipSize,
+        parent_position: ScreenPosition,
+        screen_clip: ScreenClip,
         hovered_element: Option<&dyn Element>,
         focused_element: Option<&dyn Element>,
         mouse_mode: &MouseInputMode,
@@ -114,7 +113,7 @@ impl Element for DialogContainer {
         let mut renderer = self
             .state
             .state
-            .element_renderer(render_target, renderer, interface_settings, parent_position, clip_size);
+            .element_renderer(render_target, renderer, interface_settings, parent_position, screen_clip);
 
         self.state.render(
             &mut renderer,
diff --git a/src/interface/elements/containers/equipment.rs b/src/interface/elements/containers/equipment.rs
index 2be6c88e..eb11ee17 100644
--- a/src/interface/elements/containers/equipment.rs
+++ b/src/interface/elements/containers/equipment.rs
@@ -1,4 +1,3 @@
-use cgmath::Array;
 use procedural::*;
 
 use crate::graphics::{InterfaceRenderer, Renderer};
@@ -93,7 +92,7 @@ impl Element for EquipmentContainer {
             interface_settings,
             theme,
             size_constraint,
-            Vector2::from_value(3.0),
+            ScreenSize::uniform(3.0),
         );
     }
 
@@ -113,7 +112,7 @@ impl Element for EquipmentContainer {
         None
     }
 
-    fn hovered_element(&self, mouse_position: Position, mouse_mode: &MouseInputMode) -> HoverInformation {
+    fn hovered_element(&self, mouse_position: ScreenPosition, mouse_mode: &MouseInputMode) -> HoverInformation {
         match mouse_mode {
             MouseInputMode::MoveItem(..) | MouseInputMode::None => self.state.hovered_element(mouse_position, mouse_mode, false),
             _ => HoverInformation::Missed,
@@ -127,8 +126,8 @@ impl Element for EquipmentContainer {
         state_provider: &StateProvider,
         interface_settings: &InterfaceSettings,
         theme: &InterfaceTheme,
-        parent_position: Position,
-        clip_size: ClipSize,
+        parent_position: ScreenPosition,
+        screen_clip: ScreenClip,
         hovered_element: Option<&dyn Element>,
         focused_element: Option<&dyn Element>,
         mouse_mode: &MouseInputMode,
@@ -137,7 +136,7 @@ impl Element for EquipmentContainer {
         let mut renderer = self
             .state
             .state
-            .element_renderer(render_target, renderer, interface_settings, parent_position, clip_size);
+            .element_renderer(render_target, renderer, interface_settings, parent_position, screen_clip);
 
         self.state.render(
             &mut renderer,
diff --git a/src/interface/elements/containers/expandable.rs b/src/interface/elements/containers/expandable.rs
index 804dbd6d..aaafcf22 100644
--- a/src/interface/elements/containers/expandable.rs
+++ b/src/interface/elements/containers/expandable.rs
@@ -1,6 +1,5 @@
 use std::rc::Weak;
 
-use num::Zero;
 use procedural::*;
 
 use crate::graphics::{InterfaceRenderer, Renderer};
@@ -12,7 +11,7 @@ pub struct Expandable {
     expanded: bool,
     open_size_constraint: SizeConstraint,
     closed_size_constraint: SizeConstraint,
-    cached_closed_size: Size,
+    cached_closed_size: ScreenSize,
     state: ContainerState,
 }
 
@@ -25,7 +24,7 @@ impl Expandable {
             expanded,
             open_size_constraint: constraint!(100%, ?),
             closed_size_constraint: constraint!(100%, 18),
-            cached_closed_size: Size::zero(),
+            cached_closed_size: ScreenSize::default(),
             state,
         }
     }
@@ -73,12 +72,22 @@ impl Element for Expandable {
         };
 
         if self.expanded && !self.state.elements.is_empty() {
-            let mut inner_placement_resolver = placement_resolver.derive(
-                size,
-                Position::new(0.0, closed_size.y) + *theme.expandable.element_offset * *interface_settings.scaling,
-                *theme.expandable.border_size,
-            );
-            inner_placement_resolver.set_gaps(*theme.expandable.gaps);
+            let screen_position = ScreenPosition::only_top(closed_size.height)
+                + ScreenPosition {
+                    left: theme.expandable.element_offset.x,
+                    top: theme.expandable.element_offset.y,
+                } * *interface_settings.scaling;
+
+            let screen_size = ScreenSize {
+                width: theme.expandable.border_size.x,
+                height: theme.expandable.border_size.y,
+            };
+
+            let mut inner_placement_resolver = placement_resolver.derive(size, screen_position, screen_size);
+            inner_placement_resolver.set_gaps(ScreenSize {
+                width: theme.expandable.gaps.x,
+                height: theme.expandable.gaps.y,
+            });
 
             self.state.elements.iter_mut().for_each(|element| {
                 element
@@ -88,16 +97,18 @@ impl Element for Expandable {
 
             if self.open_size_constraint.height.is_flexible() {
                 let final_height = inner_placement_resolver.final_height()
-                    + closed_size.y
+                    + closed_size.height
                     + theme.expandable.element_offset.y * *interface_settings.scaling
                     + theme.expandable.border_size.y * *interface_settings.scaling * 2.0;
+
                 let final_height = self.open_size_constraint.validated_height(
                     final_height,
-                    placement_resolver.get_available().y,
-                    placement_resolver.get_available().y,
+                    placement_resolver.get_available().height,
+                    placement_resolver.get_available().height,
                     *interface_settings.scaling,
                 );
-                size.y = Some(final_height);
+
+                size.height = Some(final_height);
                 placement_resolver.register_height(final_height);
             }
         }
@@ -115,13 +126,13 @@ impl Element for Expandable {
         self.state.update()
     }
 
-    fn hovered_element(&self, mouse_position: Position, mouse_mode: &MouseInputMode) -> HoverInformation {
-        let absolute_position = mouse_position - self.state.state.cached_position;
+    fn hovered_element(&self, mouse_position: ScreenPosition, mouse_mode: &MouseInputMode) -> HoverInformation {
+        let absolute_position = ScreenPosition::from_size(mouse_position - self.state.state.cached_position);
 
-        if absolute_position.x >= 0.0
-            && absolute_position.y >= 0.0
-            && absolute_position.x <= self.state.state.cached_size.x
-            && absolute_position.y <= self.state.state.cached_size.y
+        if absolute_position.left >= 0.0
+            && absolute_position.top >= 0.0
+            && absolute_position.left <= self.state.state.cached_size.width
+            && absolute_position.top <= self.state.state.cached_size.height
         {
             if self.expanded && !self.state.elements.is_empty() {
                 for element in &self.state.elements {
@@ -154,8 +165,8 @@ impl Element for Expandable {
         state_provider: &StateProvider,
         interface_settings: &InterfaceSettings,
         theme: &InterfaceTheme,
-        parent_position: Position,
-        clip_size: ClipSize,
+        parent_position: ScreenPosition,
+        screen_clip: ScreenClip,
         hovered_element: Option<&dyn Element>,
         focused_element: Option<&dyn Element>,
         mouse_mode: &MouseInputMode,
@@ -164,33 +175,38 @@ impl Element for Expandable {
         let mut renderer = self
             .state
             .state
-            .element_renderer(render_target, renderer, interface_settings, parent_position, clip_size);
+            .element_renderer(render_target, renderer, interface_settings, parent_position, screen_clip);
 
         let background_color = match second_theme {
             true => *theme.expandable.second_background_color,
             false => *theme.expandable.background_color,
         };
 
-        renderer.render_background(*theme.button.border_radius, background_color);
+        renderer.render_background((*theme.button.corner_radius).into(), background_color);
+
+        let arrow_position = ScreenPosition {
+            left: theme.expandable.icon_offset.x,
+            top: theme.expandable.icon_offset.y,
+        };
+
+        let arrow_size = ScreenSize {
+            width: theme.expandable.icon_size.x,
+            height: theme.expandable.icon_size.y,
+        };
 
-        renderer.render_expand_arrow(
-            *theme.expandable.icon_offset,
-            *theme.expandable.icon_size,
-            *theme.expandable.foreground_color,
-            self.expanded,
-        );
+        renderer.render_expand_arrow(arrow_position, arrow_size, *theme.expandable.foreground_color, self.expanded);
 
         let foreground_color = match self.is_element_self(hovered_element) || self.is_element_self(focused_element) {
             true => *theme.expandable.hovered_foreground_color,
             false => *theme.expandable.foreground_color,
         };
 
-        renderer.render_text(
-            &self.display,
-            *theme.expandable.text_offset,
-            foreground_color,
-            *theme.expandable.font_size,
-        );
+        let text_position = ScreenPosition {
+            left: theme.expandable.text_offset.x,
+            top: theme.expandable.text_offset.y,
+        };
+
+        renderer.render_text(&self.display, text_position, foreground_color, *theme.expandable.font_size);
 
         if self.expanded && !self.state.elements.is_empty() {
             self.state.render(
diff --git a/src/interface/elements/containers/friends.rs b/src/interface/elements/containers/friends.rs
index 37706853..aaacf27f 100644
--- a/src/interface/elements/containers/friends.rs
+++ b/src/interface/elements/containers/friends.rs
@@ -1,7 +1,6 @@
 use std::cell::UnsafeCell;
 use std::rc::Weak;
 
-use cgmath::Zero;
 use procedural::*;
 
 use crate::graphics::{InterfaceRenderer, Renderer};
@@ -81,7 +80,7 @@ impl Element for FriendView {
             interface_settings,
             theme,
             &constraint!(100%, ?),
-            Vector2::zero(),
+            ScreenSize::default(),
         );
     }
 
@@ -126,7 +125,7 @@ impl Element for FriendView {
         }
     }
 
-    fn hovered_element(&self, mouse_position: Position, mouse_mode: &MouseInputMode) -> HoverInformation {
+    fn hovered_element(&self, mouse_position: ScreenPosition, mouse_mode: &MouseInputMode) -> HoverInformation {
         match mouse_mode {
             MouseInputMode::None => self.state.hovered_element(mouse_position, mouse_mode, false),
             _ => HoverInformation::Missed,
@@ -140,8 +139,8 @@ impl Element for FriendView {
         state_provider: &StateProvider,
         interface_settings: &InterfaceSettings,
         theme: &InterfaceTheme,
-        parent_position: Position,
-        clip_size: ClipSize,
+        parent_position: ScreenPosition,
+        screen_clip: ScreenClip,
         hovered_element: Option<&dyn Element>,
         focused_element: Option<&dyn Element>,
         mouse_mode: &MouseInputMode,
@@ -150,7 +149,7 @@ impl Element for FriendView {
         let mut renderer = self
             .state
             .state
-            .element_renderer(render_target, renderer, interface_settings, parent_position, clip_size);
+            .element_renderer(render_target, renderer, interface_settings, parent_position, screen_clip);
 
         self.state.render(
             &mut renderer,
diff --git a/src/interface/elements/containers/hotbar.rs b/src/interface/elements/containers/hotbar.rs
index 8515e84a..7797fcbe 100644
--- a/src/interface/elements/containers/hotbar.rs
+++ b/src/interface/elements/containers/hotbar.rs
@@ -1,4 +1,3 @@
-use cgmath::Array;
 use procedural::*;
 
 use crate::graphics::{InterfaceRenderer, Renderer};
@@ -71,7 +70,7 @@ impl Element for HotbarContainer {
             interface_settings,
             theme,
             size_constraint,
-            Vector2::from_value(3.0),
+            ScreenSize::uniform(3.0),
         );
     }
 
@@ -91,7 +90,7 @@ impl Element for HotbarContainer {
         None
     }
 
-    fn hovered_element(&self, mouse_position: Position, mouse_mode: &MouseInputMode) -> HoverInformation {
+    fn hovered_element(&self, mouse_position: ScreenPosition, mouse_mode: &MouseInputMode) -> HoverInformation {
         match mouse_mode {
             MouseInputMode::MoveSkill(..) | MouseInputMode::None => self.state.hovered_element(mouse_position, mouse_mode, false),
             _ => HoverInformation::Missed,
@@ -105,8 +104,8 @@ impl Element for HotbarContainer {
         state_provider: &StateProvider,
         interface_settings: &InterfaceSettings,
         theme: &InterfaceTheme,
-        parent_position: Position,
-        clip_size: ClipSize,
+        parent_position: ScreenPosition,
+        screen_clip: ScreenClip,
         hovered_element: Option<&dyn Element>,
         focused_element: Option<&dyn Element>,
         mouse_mode: &MouseInputMode,
@@ -115,7 +114,7 @@ impl Element for HotbarContainer {
         let mut renderer = self
             .state
             .state
-            .element_renderer(render_target, renderer, interface_settings, parent_position, clip_size);
+            .element_renderer(render_target, renderer, interface_settings, parent_position, screen_clip);
 
         self.state.render(
             &mut renderer,
diff --git a/src/interface/elements/containers/inventory.rs b/src/interface/elements/containers/inventory.rs
index 4f4670eb..44820ff0 100644
--- a/src/interface/elements/containers/inventory.rs
+++ b/src/interface/elements/containers/inventory.rs
@@ -1,4 +1,3 @@
-use cgmath::{Array, Vector4};
 use procedural::*;
 
 use crate::graphics::{InterfaceRenderer, Renderer};
@@ -64,7 +63,7 @@ impl Element for InventoryContainer {
             interface_settings,
             theme,
             size_constraint,
-            Vector2::from_value(3.0),
+            ScreenSize::uniform(3.0),
         );
     }
 
@@ -84,7 +83,7 @@ impl Element for InventoryContainer {
         None
     }
 
-    fn hovered_element(&self, mouse_position: Position, mouse_mode: &MouseInputMode) -> HoverInformation {
+    fn hovered_element(&self, mouse_position: ScreenPosition, mouse_mode: &MouseInputMode) -> HoverInformation {
         match mouse_mode {
             MouseInputMode::MoveItem(..) => self.state.state.hovered_element(mouse_position),
             MouseInputMode::None => self.state.hovered_element(mouse_position, mouse_mode, false),
@@ -107,8 +106,8 @@ impl Element for InventoryContainer {
         state_provider: &StateProvider,
         interface_settings: &InterfaceSettings,
         theme: &InterfaceTheme,
-        parent_position: Position,
-        clip_size: ClipSize,
+        parent_position: ScreenPosition,
+        screen_clip: ScreenClip,
         hovered_element: Option<&dyn Element>,
         focused_element: Option<&dyn Element>,
         mouse_mode: &MouseInputMode,
@@ -117,7 +116,7 @@ impl Element for InventoryContainer {
         let mut renderer = self
             .state
             .state
-            .element_renderer(render_target, renderer, interface_settings, parent_position, clip_size);
+            .element_renderer(render_target, renderer, interface_settings, parent_position, screen_clip);
 
         self.state.render(
             &mut renderer,
@@ -132,8 +131,8 @@ impl Element for InventoryContainer {
 
         if matches!(mouse_mode, MouseInputMode::MoveItem(..)) {
             match self.is_element_self(hovered_element) {
-                true => renderer.render_background(Vector4::from_value(5.0), Color::rgba(60, 160, 160, 160)),
-                false => renderer.render_background(Vector4::from_value(5.0), Color::rgba(160, 160, 60, 160)),
+                true => renderer.render_background(CornerRadius::uniform(5.0), Color::rgba(60, 160, 160, 160)),
+                false => renderer.render_background(CornerRadius::uniform(5.0), Color::rgba(160, 160, 60, 160)),
             }
         }
     }
diff --git a/src/interface/elements/containers/mod.rs b/src/interface/elements/containers/mod.rs
index 1de3035b..49dfa764 100644
--- a/src/interface/elements/containers/mod.rs
+++ b/src/interface/elements/containers/mod.rs
@@ -15,7 +15,6 @@ use std::cell::Cell;
 use std::ops::Add;
 use std::rc::Weak;
 
-use cgmath::Zero;
 use derive_new::new;
 
 pub use self::character::CharacterPreview;
@@ -57,10 +56,10 @@ impl ContainerState {
         interface_settings: &InterfaceSettings,
         theme: &InterfaceTheme,
         size_constraint: &SizeConstraint,
-        border: Vector2<f32>,
+        border: ScreenSize,
     ) {
         let (mut size, position) = placement_resolver.allocate(size_constraint);
-        let mut inner_placement_resolver = placement_resolver.derive(size, Position::zero(), border);
+        let mut inner_placement_resolver = placement_resolver.derive(size, ScreenPosition::default(), border);
 
         // TODO: add ability to pass this in (by calling .with_gaps(..) on the
         // container) inner_placement_resolver.set_gaps(Size::new(5.0, 3.0));
@@ -75,11 +74,11 @@ impl ContainerState {
             let final_height = inner_placement_resolver.final_height();
             let final_height = size_constraint.validated_height(
                 final_height,
-                placement_resolver.get_available().y,
-                placement_resolver.get_available().y,
+                placement_resolver.get_available().height,
+                placement_resolver.get_available().height,
                 *interface_settings.scaling,
             );
-            size.y = Some(final_height);
+            size.height = Some(final_height);
             placement_resolver.register_height(final_height);
         }
 
@@ -270,13 +269,13 @@ impl ContainerState {
             })
     }
 
-    pub fn hovered_element(&self, mouse_position: Position, mouse_mode: &MouseInputMode, hoverable: bool) -> HoverInformation {
-        let absolute_position = mouse_position - self.state.cached_position;
+    pub fn hovered_element(&self, mouse_position: ScreenPosition, mouse_mode: &MouseInputMode, hoverable: bool) -> HoverInformation {
+        let absolute_position = ScreenPosition::from_size(mouse_position - self.state.cached_position);
 
-        if absolute_position.x >= 0.0
-            && absolute_position.y >= 0.0
-            && absolute_position.x <= self.state.cached_size.x
-            && absolute_position.y <= self.state.cached_size.y
+        if absolute_position.left >= 0.0
+            && absolute_position.top >= 0.0
+            && absolute_position.left <= self.state.cached_size.width
+            && absolute_position.top <= self.state.cached_size.height
         {
             for element in &self.elements {
                 match element.borrow().hovered_element(absolute_position, mouse_mode) {
diff --git a/src/interface/elements/containers/packet.rs b/src/interface/elements/containers/packet.rs
index 728046ad..7756c2d8 100644
--- a/src/interface/elements/containers/packet.rs
+++ b/src/interface/elements/containers/packet.rs
@@ -2,7 +2,6 @@ use std::cell::UnsafeCell;
 use std::fmt::{Display, Formatter, Result};
 use std::rc::Weak;
 
-use cgmath::Zero;
 use procedural::*;
 
 use crate::graphics::{InterfaceRenderer, Renderer};
@@ -31,8 +30,8 @@ impl Element for HiddenElement {
         _state_provider: &StateProvider,
         _interface_settings: &InterfaceSettings,
         _theme: &InterfaceTheme,
-        _parent_position: Position,
-        _clip_size: ClipSize,
+        _parent_position: ScreenPosition,
+        _screen_clip: ScreenClip,
         _hovered_element: Option<&dyn Element>,
         _focused_element: Option<&dyn Element>,
         _mouse_mode: &MouseInputMode,
@@ -165,7 +164,7 @@ impl<const N: usize> Element for PacketView<N> {
             interface_settings,
             theme,
             &constraint!(100%, ?),
-            Vector2::zero(),
+            ScreenSize::default(),
         );
     }
 
@@ -265,7 +264,7 @@ impl<const N: usize> Element for PacketView<N> {
         }
     }
 
-    fn hovered_element(&self, mouse_position: Position, mouse_mode: &MouseInputMode) -> HoverInformation {
+    fn hovered_element(&self, mouse_position: ScreenPosition, mouse_mode: &MouseInputMode) -> HoverInformation {
         match mouse_mode {
             MouseInputMode::None => self.state.hovered_element(mouse_position, mouse_mode, false),
             _ => HoverInformation::Missed,
@@ -279,8 +278,8 @@ impl<const N: usize> Element for PacketView<N> {
         state_provider: &StateProvider,
         interface_settings: &InterfaceSettings,
         theme: &InterfaceTheme,
-        parent_position: Position,
-        clip_size: ClipSize,
+        parent_position: ScreenPosition,
+        screen_clip: ScreenClip,
         hovered_element: Option<&dyn Element>,
         focused_element: Option<&dyn Element>,
         mouse_mode: &MouseInputMode,
@@ -289,7 +288,7 @@ impl<const N: usize> Element for PacketView<N> {
         let mut renderer = self
             .state
             .state
-            .element_renderer(render_target, renderer, interface_settings, parent_position, clip_size);
+            .element_renderer(render_target, renderer, interface_settings, parent_position, screen_clip);
 
         self.state.render(
             &mut renderer,
diff --git a/src/interface/elements/containers/scroll.rs b/src/interface/elements/containers/scroll.rs
index e894c3ce..2153d536 100644
--- a/src/interface/elements/containers/scroll.rs
+++ b/src/interface/elements/containers/scroll.rs
@@ -1,7 +1,5 @@
 use std::rc::Weak;
 
-use cgmath::Zero;
-
 use crate::graphics::{InterfaceRenderer, Renderer};
 use crate::input::MouseInputMode;
 use crate::interface::{Element, *};
@@ -66,7 +64,7 @@ impl Element for ScrollView {
             interface_settings,
             theme,
             &self.size_constraint,
-            Vector2::zero(),
+            ScreenSize::default(),
         );
     }
 
@@ -74,9 +72,9 @@ impl Element for ScrollView {
         self.state.update()
     }
 
-    fn hovered_element(&self, mouse_position: Position, mouse_mode: &MouseInputMode) -> HoverInformation {
+    fn hovered_element(&self, mouse_position: ScreenPosition, mouse_mode: &MouseInputMode) -> HoverInformation {
         self.state.hovered_element(
-            mouse_position + Vector2::new(0.0, self.scroll),
+            mouse_position + ScreenPosition::only_top(self.scroll),
             mouse_mode,
             mouse_mode.is_none(),
         )
@@ -95,8 +93,8 @@ impl Element for ScrollView {
         state_provider: &StateProvider,
         interface_settings: &InterfaceSettings,
         theme: &InterfaceTheme,
-        parent_position: Position,
-        clip_size: ClipSize,
+        parent_position: ScreenPosition,
+        screen_clip: ScreenClip,
         hovered_element: Option<&dyn Element>,
         focused_element: Option<&dyn Element>,
         mouse_mode: &MouseInputMode,
@@ -105,7 +103,7 @@ impl Element for ScrollView {
         let mut renderer = self
             .state
             .state
-            .element_renderer(render_target, renderer, interface_settings, parent_position, clip_size);
+            .element_renderer(render_target, renderer, interface_settings, parent_position, screen_clip);
 
         if let Some(color_selector) = &self.background_color {
             renderer.render_background((*theme.button.corner_radius).into(), color_selector(theme));
diff --git a/src/interface/elements/containers/skill_tree.rs b/src/interface/elements/containers/skill_tree.rs
index d0f451b2..7c5d8604 100644
--- a/src/interface/elements/containers/skill_tree.rs
+++ b/src/interface/elements/containers/skill_tree.rs
@@ -1,4 +1,3 @@
-use cgmath::Array;
 use procedural::*;
 
 use crate::graphics::{InterfaceRenderer, Renderer};
@@ -64,7 +63,7 @@ impl Element for SkillTreeContainer {
             interface_settings,
             theme,
             size_constraint,
-            Vector2::from_value(3.0),
+            ScreenSize::uniform(3.0),
         );
     }
 
@@ -84,7 +83,7 @@ impl Element for SkillTreeContainer {
         None
     }
 
-    fn hovered_element(&self, mouse_position: Position, mouse_mode: &MouseInputMode) -> HoverInformation {
+    fn hovered_element(&self, mouse_position: ScreenPosition, mouse_mode: &MouseInputMode) -> HoverInformation {
         match mouse_mode {
             MouseInputMode::MoveItem(..) => self.state.state.hovered_element(mouse_position),
             MouseInputMode::None => self.state.hovered_element(mouse_position, mouse_mode, false),
@@ -107,8 +106,8 @@ impl Element for SkillTreeContainer {
         state_provider: &StateProvider,
         interface_settings: &InterfaceSettings,
         theme: &InterfaceTheme,
-        parent_position: Position,
-        clip_size: ClipSize,
+        parent_position: ScreenPosition,
+        screen_clip: ScreenClip,
         hovered_element: Option<&dyn Element>,
         focused_element: Option<&dyn Element>,
         mouse_mode: &MouseInputMode,
@@ -117,7 +116,7 @@ impl Element for SkillTreeContainer {
         let mut renderer = self
             .state
             .state
-            .element_renderer(render_target, renderer, interface_settings, parent_position, clip_size);
+            .element_renderer(render_target, renderer, interface_settings, parent_position, screen_clip);
 
         self.state.render(
             &mut renderer,
diff --git a/src/interface/elements/miscellanious/chat.rs b/src/interface/elements/miscellanious/chat.rs
index 7cec8850..460aded3 100644
--- a/src/interface/elements/miscellanious/chat.rs
+++ b/src/interface/elements/miscellanious/chat.rs
@@ -1,4 +1,3 @@
-use cgmath::Array;
 use procedural::*;
 
 use crate::graphics::{InterfaceRenderer, Renderer};
@@ -57,7 +56,7 @@ impl Element for Chat {
                 .get_text_dimensions(
                     message.stamped_text(self.stamp),
                     *theme.chat.font_size * *interface_settings.scaling,
-                    placement_resolver.get_available().x,
+                    placement_resolver.get_available().width,
                 )
                 .y;
         }
@@ -84,8 +83,8 @@ impl Element for Chat {
         _state_provider: &StateProvider,
         interface_settings: &InterfaceSettings,
         theme: &InterfaceTheme,
-        parent_position: Position,
-        clip_size: ClipSize,
+        parent_position: ScreenPosition,
+        screen_clip: ScreenClip,
         _hovered_element: Option<&dyn Element>,
         _focused_element: Option<&dyn Element>,
         _mouse_mode: &MouseInputMode,
@@ -93,7 +92,7 @@ impl Element for Chat {
     ) {
         let mut renderer = self
             .state
-            .element_renderer(render_target, renderer, interface_settings, parent_position, clip_size);
+            .element_renderer(render_target, renderer, interface_settings, parent_position, screen_clip);
 
         let mut offset = 0.0;
 
@@ -102,12 +101,15 @@ impl Element for Chat {
 
             renderer.render_text(
                 text,
-                Vector2::new(0.0, offset) + Vector2::from_value(0.2),
+                ScreenPosition {
+                    left: 0.2,
+                    top: offset + 0.2,
+                },
                 Color::monochrome(0),
                 *theme.chat.font_size,
             );
 
-            offset += renderer.render_text(text, Vector2::new(0.0, offset), message.color, *theme.chat.font_size);
+            offset += renderer.render_text(text, ScreenPosition::only_top(offset), message.color, *theme.chat.font_size);
         }
     }
 }
diff --git a/src/interface/elements/miscellanious/headline.rs b/src/interface/elements/miscellanious/headline.rs
index 61723575..294a9543 100644
--- a/src/interface/elements/miscellanious/headline.rs
+++ b/src/interface/elements/miscellanious/headline.rs
@@ -40,8 +40,8 @@ impl Element for Headline {
         _state_provider: &StateProvider,
         interface_settings: &InterfaceSettings,
         theme: &InterfaceTheme,
-        parent_position: Position,
-        clip_size: ClipSize,
+        parent_position: ScreenPosition,
+        screen_clip: ScreenClip,
         _hovered_element: Option<&dyn Element>,
         _focused_element: Option<&dyn Element>,
         _mouse_mode: &MouseInputMode,
@@ -49,11 +49,16 @@ impl Element for Headline {
     ) {
         let mut renderer = self
             .state
-            .element_renderer(render_target, renderer, interface_settings, parent_position, clip_size);
+            .element_renderer(render_target, renderer, interface_settings, parent_position, screen_clip);
+
+        let text_position = ScreenPosition {
+            left: theme.label.text_offset.x,
+            top: theme.label.text_offset.y,
+        };
 
         renderer.render_text(
             &self.display,
-            *theme.label.text_offset,
+            text_position,
             *theme.label.foreground_color,
             *theme.label.font_size,
         );
diff --git a/src/interface/elements/miscellanious/input.rs b/src/interface/elements/miscellanious/input.rs
index 2599217c..4dfca7f2 100644
--- a/src/interface/elements/miscellanious/input.rs
+++ b/src/interface/elements/miscellanious/input.rs
@@ -1,7 +1,6 @@
 use std::cell::RefCell;
 use std::rc::Rc;
 
-use cgmath::{Array, Vector2, Vector4};
 use derive_new::new;
 
 use crate::graphics::{InterfaceRenderer, Renderer};
@@ -56,7 +55,7 @@ impl<const LENGTH: usize, const HIDDEN: bool> Element for InputField<LENGTH, HID
         self.state.resolve(placement_resolver, &size_constraint);
     }
 
-    fn hovered_element(&self, mouse_position: Position, mouse_mode: &MouseInputMode) -> HoverInformation {
+    fn hovered_element(&self, mouse_position: ScreenPosition, mouse_mode: &MouseInputMode) -> HoverInformation {
         match mouse_mode {
             MouseInputMode::None => self.state.hovered_element(mouse_position),
             _ => HoverInformation::Missed,
@@ -82,8 +81,8 @@ impl<const LENGTH: usize, const HIDDEN: bool> Element for InputField<LENGTH, HID
         _state_provider: &StateProvider,
         interface_settings: &InterfaceSettings,
         theme: &InterfaceTheme,
-        parent_position: Position,
-        clip_size: ClipSize,
+        parent_position: ScreenPosition,
+        screen_clip: ScreenClip,
         hovered_element: Option<&dyn Element>,
         focused_element: Option<&dyn Element>,
         _mouse_mode: &MouseInputMode,
@@ -91,7 +90,7 @@ impl<const LENGTH: usize, const HIDDEN: bool> Element for InputField<LENGTH, HID
     ) {
         let mut renderer = self
             .state
-            .element_renderer(render_target, renderer, interface_settings, parent_position, clip_size);
+            .element_renderer(render_target, renderer, interface_settings, parent_position, screen_clip);
 
         let display: &String = &RefCell::borrow(&self.display);
         let is_hovererd = self.is_element_self(hovered_element);
@@ -122,18 +121,33 @@ impl<const LENGTH: usize, const HIDDEN: bool> Element for InputField<LENGTH, HID
             *theme.input.text_color
         };
 
-        renderer.render_background(*theme.input.border_radius, background_color);
-        renderer.render_text(&text, text_offset, text_color, *theme.input.font_size);
+        let text_position = ScreenPosition {
+            left: text_offset.x,
+            top: text_offset.y,
+        };
+
+        renderer.render_background((*theme.input.corner_radius).into(), background_color);
+        renderer.render_text(&text, text_position, text_color, *theme.input.font_size);
 
         if is_focused {
             let cursor_offset = text_offset.x
                 + *theme.input.cursor_offset * *interface_settings.scaling
                 + renderer.get_text_dimensions(&text, *theme.input.font_size, f32::MAX).x;
 
+            let cursor_position = ScreenPosition {
+                left: cursor_offset,
+                top: 0.0,
+            };
+
+            let cursor_size = ScreenSize {
+                width: *theme.input.cursor_width,
+                height: self.state.cached_size.height,
+            };
+
             renderer.render_rectangle(
-                Vector2::new(cursor_offset, 0.0),
-                Vector2::new(*theme.input.cursor_width, self.state.cached_size.y),
-                Vector4::from_value(0.0),
+                cursor_position,
+                cursor_size,
+                CornerRadius::uniform(0.0),
                 *theme.input.text_color,
             );
         }
diff --git a/src/interface/elements/miscellanious/item.rs b/src/interface/elements/miscellanious/item.rs
index 47c71b8b..08a9c475 100644
--- a/src/interface/elements/miscellanious/item.rs
+++ b/src/interface/elements/miscellanious/item.rs
@@ -1,4 +1,3 @@
-use cgmath::{Array, Vector4, Zero};
 use derive_new::new;
 use procedural::*;
 
@@ -33,7 +32,7 @@ impl Element for ItemBox {
         self.state.resolve(placement_resolver, &constraint!(30, 30));
     }
 
-    fn hovered_element(&self, mouse_position: Position, mouse_mode: &MouseInputMode) -> HoverInformation {
+    fn hovered_element(&self, mouse_position: ScreenPosition, mouse_mode: &MouseInputMode) -> HoverInformation {
         match self.item.is_some() || matches!(mouse_mode, MouseInputMode::MoveItem(..)) {
             true => self.state.hovered_element(mouse_position),
             false => HoverInformation::Missed,
@@ -63,8 +62,8 @@ impl Element for ItemBox {
         _state_provider: &StateProvider,
         interface_settings: &InterfaceSettings,
         theme: &InterfaceTheme,
-        parent_position: Position,
-        clip_size: ClipSize,
+        parent_position: ScreenPosition,
+        screen_clip: ScreenClip,
         hovered_element: Option<&dyn Element>,
         focused_element: Option<&dyn Element>,
         mouse_mode: &MouseInputMode,
@@ -72,7 +71,7 @@ impl Element for ItemBox {
     ) {
         let mut renderer = self
             .state
-            .element_renderer(render_target, renderer, interface_settings, parent_position, clip_size);
+            .element_renderer(render_target, renderer, interface_settings, parent_position, screen_clip);
 
         let highlight = (self.highlight)(mouse_mode);
         let background_color = match self.is_element_self(hovered_element) || self.is_element_self(focused_element) {
@@ -82,20 +81,20 @@ impl Element for ItemBox {
             _ => *theme.button.background_color,
         };
 
-        renderer.render_background(Vector4::from_value(5.0), background_color);
+        renderer.render_background(CornerRadius::uniform(5.0), background_color);
 
         if let Some(item) = &self.item {
             renderer.render_sprite(
                 item.texture.clone(),
-                Vector2::zero(),
-                Vector2::from_value(30.0),
+                ScreenPosition::default(),
+                ScreenSize::uniform(30.0),
                 Color::monochrome(255),
             );
 
             renderer.render_text(
                 //&format!("{}", self.item.amount),
                 "1",
-                Vector2::zero(),
+                ScreenPosition::default(),
                 *theme.button.foreground_color,
                 8.0,
             );
diff --git a/src/interface/elements/miscellanious/picklist.rs b/src/interface/elements/miscellanious/picklist.rs
index 8b9c358b..7ef29ccf 100644
--- a/src/interface/elements/miscellanious/picklist.rs
+++ b/src/interface/elements/miscellanious/picklist.rs
@@ -15,8 +15,8 @@ where
     event: Option<E>,
     width_constraint: Option<DimensionConstraint>,
     state: ElementState,
-    latest_position: Rc<RefCell<Position>>,
-    latest_size: Rc<RefCell<Size>>,
+    latest_position: Rc<RefCell<ScreenPosition>>,
+    latest_size: Rc<RefCell<ScreenSize>>,
 }
 
 // HACK: Workaround for Rust incorrect trait bounds when deriving Option<T>
@@ -34,8 +34,8 @@ where
             event: Default::default(),
             width_constraint: Default::default(),
             state: Default::default(),
-            latest_position: Rc::new(RefCell::new(Position::new(0.0, 0.0))),
-            latest_size: Rc::new(RefCell::new(Size::new(0.0, 0.0))),
+            latest_position: Rc::new(RefCell::new(ScreenPosition::default())),
+            latest_size: Rc::new(RefCell::new(ScreenSize::default())),
         }
     }
 }
@@ -93,7 +93,7 @@ where
         *self.latest_size.borrow_mut() = self.state.cached_size;
     }
 
-    fn hovered_element(&self, mouse_position: Position, mouse_mode: &MouseInputMode) -> HoverInformation {
+    fn hovered_element(&self, mouse_position: ScreenPosition, mouse_mode: &MouseInputMode) -> HoverInformation {
         match mouse_mode {
             MouseInputMode::None => self.state.hovered_element(mouse_position),
             _ => HoverInformation::Missed,
@@ -154,8 +154,8 @@ where
         _state_provider: &StateProvider,
         interface_settings: &InterfaceSettings,
         theme: &InterfaceTheme,
-        parent_position: Position,
-        clip_size: ClipSize,
+        parent_position: ScreenPosition,
+        screen_clip: ScreenClip,
         hovered_element: Option<&dyn Element>,
         focused_element: Option<&dyn Element>,
         _mouse_mode: &MouseInputMode,
@@ -163,7 +163,7 @@ where
     ) {
         let mut renderer = self
             .state
-            .element_renderer(render_target, renderer, interface_settings, parent_position, clip_size);
+            .element_renderer(render_target, renderer, interface_settings, parent_position, screen_clip);
 
         let highlighted = self.is_element_self(hovered_element) || self.is_element_self(focused_element);
         let background_color = match highlighted {
@@ -171,7 +171,7 @@ where
             false => *theme.button.background_color,
         };
 
-        renderer.render_background(*theme.button.border_radius, background_color);
+        renderer.render_background((*theme.button.corner_radius).into(), background_color);
 
         *self.latest_position.borrow_mut() = renderer.get_position();
 
@@ -184,12 +184,12 @@ where
         let current_state = self.selected.as_ref().map(|state| state.get()).unwrap();
 
         if let Some((text, _)) = self.options.iter().find(|(_, value)| *value == current_state) {
-            renderer.render_text(
-                text.as_ref(),
-                *theme.button.text_offset,
-                foreground_color,
-                *theme.button.font_size,
-            );
+            let text_position = ScreenPosition {
+                left: theme.button.text_offset.x,
+                top: theme.button.text_offset.y,
+            };
+
+            renderer.render_text(text.as_ref(), text_position, foreground_color, *theme.button.font_size);
         }
     }
 }
diff --git a/src/interface/elements/miscellanious/skill.rs b/src/interface/elements/miscellanious/skill.rs
index e21c5ebd..ac4ae5b4 100644
--- a/src/interface/elements/miscellanious/skill.rs
+++ b/src/interface/elements/miscellanious/skill.rs
@@ -1,4 +1,3 @@
-use cgmath::{Array, Vector4, Zero};
 use derive_new::new;
 use procedural::*;
 
@@ -33,7 +32,7 @@ impl Element for SkillBox {
         self.state.resolve(placement_resolver, &constraint!(30, 30));
     }
 
-    fn hovered_element(&self, mouse_position: Position, mouse_mode: &MouseInputMode) -> HoverInformation {
+    fn hovered_element(&self, mouse_position: ScreenPosition, mouse_mode: &MouseInputMode) -> HoverInformation {
         match self.skill.is_some() || matches!(mouse_mode, MouseInputMode::MoveSkill(..)) {
             true => self.state.hovered_element(mouse_position),
             false => HoverInformation::Missed,
@@ -63,8 +62,8 @@ impl Element for SkillBox {
         _state_provider: &StateProvider,
         interface_settings: &InterfaceSettings,
         theme: &InterfaceTheme,
-        parent_position: Position,
-        clip_size: ClipSize,
+        parent_position: ScreenPosition,
+        screen_clip: ScreenClip,
         hovered_element: Option<&dyn Element>,
         focused_element: Option<&dyn Element>,
         mouse_mode: &MouseInputMode,
@@ -72,7 +71,7 @@ impl Element for SkillBox {
     ) {
         let mut renderer = self
             .state
-            .element_renderer(render_target, renderer, interface_settings, parent_position, clip_size);
+            .element_renderer(render_target, renderer, interface_settings, parent_position, screen_clip);
 
         let highlight = (self.highlight)(mouse_mode);
         let background_color = match self.is_element_self(hovered_element) || self.is_element_self(focused_element) {
@@ -82,7 +81,7 @@ impl Element for SkillBox {
             _ => *theme.button.background_color,
         };
 
-        renderer.render_background(Vector4::from_value(5.0), background_color);
+        renderer.render_background(CornerRadius::uniform(5.0), background_color);
 
         if let Some(skill) = &self.skill {
             skill.actions.render2(
@@ -90,7 +89,7 @@ impl Element for SkillBox {
                 renderer.renderer,
                 &skill.sprite,
                 &skill.animation_state,
-                renderer.position + Vector2::from_value(15.0 * *interface_settings.scaling),
+                renderer.position + ScreenPosition::uniform(15.0 * *interface_settings.scaling),
                 0,
                 Color::monochrome(255),
                 interface_settings,
@@ -98,13 +97,13 @@ impl Element for SkillBox {
 
             renderer.render_text(
                 &format!("{}", skill.skill_level.0),
-                Vector2::from_value(1.0),
+                ScreenPosition::uniform(1.0),
                 Color::monochrome(0),
                 15.0,
             );
             renderer.render_text(
                 &format!("{}", skill.skill_level.0),
-                Vector2::zero(),
+                ScreenPosition::default(),
                 Color::monochrome(255),
                 15.0,
             );
diff --git a/src/interface/elements/miscellanious/slider.rs b/src/interface/elements/miscellanious/slider.rs
index 335f29a0..9874bd0f 100644
--- a/src/interface/elements/miscellanious/slider.rs
+++ b/src/interface/elements/miscellanious/slider.rs
@@ -1,6 +1,5 @@
 use std::cmp::PartialOrd;
 
-use cgmath::{Array, Vector4};
 use derive_new::new;
 use num::traits::NumOps;
 use num::{clamp, NumCast, Zero};
@@ -45,7 +44,7 @@ impl<T: Zero + NumOps + NumCast + Copy + PartialOrd> Element for Slider<T> {
         None
     }
 
-    fn hovered_element(&self, mouse_position: Position, mouse_mode: &MouseInputMode) -> HoverInformation {
+    fn hovered_element(&self, mouse_position: ScreenPosition, mouse_mode: &MouseInputMode) -> HoverInformation {
         match mouse_mode {
             MouseInputMode::None => self.state.hovered_element(mouse_position),
             MouseInputMode::DragElement((element, _)) if self.is_element_self(Some(&*element.borrow())) => HoverInformation::Hovered,
@@ -57,9 +56,9 @@ impl<T: Zero + NumOps + NumCast + Copy + PartialOrd> Element for Slider<T> {
         vec![ClickAction::DragElement]
     }
 
-    fn drag(&mut self, mouse_delta: Position) -> Option<ChangeEvent> {
+    fn drag(&mut self, mouse_delta: ScreenPosition) -> Option<ChangeEvent> {
         let total_range = self.maximum_value.to_f32().unwrap() - self.minimum_value.to_f32().unwrap();
-        let raw_value = self.cached_value.to_f32().unwrap() + (mouse_delta.x * total_range * 0.005);
+        let raw_value = self.cached_value.to_f32().unwrap() + (mouse_delta.left * total_range * 0.005);
         let new_value = clamp(
             raw_value,
             self.minimum_value.to_f32().unwrap(),
@@ -79,8 +78,8 @@ impl<T: Zero + NumOps + NumCast + Copy + PartialOrd> Element for Slider<T> {
         _state_provider: &StateProvider,
         interface_settings: &InterfaceSettings,
         theme: &InterfaceTheme,
-        parent_position: Position,
-        clip_size: ClipSize,
+        parent_position: ScreenPosition,
+        screen_clip: ScreenClip,
         hovered_element: Option<&dyn Element>,
         _focused_element: Option<&dyn Element>,
         _mouse_mode: &MouseInputMode,
@@ -88,25 +87,31 @@ impl<T: Zero + NumOps + NumCast + Copy + PartialOrd> Element for Slider<T> {
     ) {
         let mut renderer = self
             .state
-            .element_renderer(render_target, renderer, interface_settings, parent_position, clip_size);
+            .element_renderer(render_target, renderer, interface_settings, parent_position, screen_clip);
 
         if self.is_element_self(hovered_element) {
-            renderer.render_background(*theme.button.border_radius, *theme.slider.background_color);
+            renderer.render_background((*theme.button.corner_radius).into(), *theme.slider.background_color);
         }
 
-        let bar_size = Size::new(self.state.cached_size.x * 0.9, self.state.cached_size.y / 4.0);
-        let offset = (self.state.cached_size - bar_size) / 2.0;
+        let bar_size = ScreenSize {
+            width: self.state.cached_size.width * 0.9,
+            height: self.state.cached_size.height / 4.0,
+        };
+        let offset = ScreenPosition::from_size((self.state.cached_size - bar_size) / 2.0);
 
-        renderer.render_rectangle(offset, bar_size, Vector4::from_value(0.5), *theme.slider.rail_color);
+        renderer.render_rectangle(offset, bar_size, CornerRadius::uniform(0.5), *theme.slider.rail_color);
 
-        let knob_size = Size::new(20.0 * *interface_settings.scaling, self.state.cached_size.y * 0.8);
+        let knob_size = ScreenSize {
+            width: 20.0 * *interface_settings.scaling,
+            height: self.state.cached_size.height * 0.8,
+        };
         let total_range = self.maximum_value - self.minimum_value;
-        let offset = Position::new(
-            (self.state.cached_size.x - knob_size.x) / total_range.to_f32().unwrap()
+        let offset = ScreenPosition {
+            left: (self.state.cached_size.width - knob_size.width) / total_range.to_f32().unwrap()
                 * (self.cached_value.to_f32().unwrap() - self.minimum_value.to_f32().unwrap()),
-            (self.state.cached_size.y - knob_size.y) / 2.0,
-        );
+            top: (self.state.cached_size.height - knob_size.height) / 2.0,
+        };
 
-        renderer.render_rectangle(offset, knob_size, Vector4::from_value(4.0), *theme.slider.knob_color);
+        renderer.render_rectangle(offset, knob_size, CornerRadius::uniform(4.0), *theme.slider.knob_color);
     }
 }
diff --git a/src/interface/elements/miscellanious/static_label.rs b/src/interface/elements/miscellanious/static_label.rs
index 7576d31e..a03750ab 100644
--- a/src/interface/elements/miscellanious/static_label.rs
+++ b/src/interface/elements/miscellanious/static_label.rs
@@ -27,7 +27,7 @@ impl Element for StaticLabel {
             *theme.label.font_size,
             *theme.label.text_offset,
             *interface_settings.scaling,
-            placement_resolver.get_available().x / 2.0, // TODO: make better
+            placement_resolver.get_available().width / 2.0, // TODO: make better
         );
 
         size_constraint.height = Dimension::Absolute(f32::max(size.y / *interface_settings.scaling, 14.0)); // TODO: make better
@@ -42,8 +42,8 @@ impl Element for StaticLabel {
         _state_provider: &StateProvider,
         interface_settings: &InterfaceSettings,
         theme: &InterfaceTheme,
-        parent_position: Position,
-        clip_size: ClipSize,
+        parent_position: ScreenPosition,
+        screen_clip: ScreenClip,
         _hovered_element: Option<&dyn Element>,
         _focused_element: Option<&dyn Element>,
         _mouse_mode: &MouseInputMode,
@@ -51,15 +51,15 @@ impl Element for StaticLabel {
     ) {
         let mut renderer = self
             .state
-            .element_renderer(render_target, renderer, interface_settings, parent_position, clip_size);
+            .element_renderer(render_target, renderer, interface_settings, parent_position, screen_clip);
 
-        renderer.render_background(*theme.label.border_radius, *theme.label.background_color);
+        renderer.render_background((*theme.label.corner_radius).into(), *theme.label.background_color);
 
-        renderer.render_text(
-            &self.label,
-            *theme.label.text_offset,
-            *theme.label.foreground_color,
-            *theme.label.font_size,
-        );
+        let text_size = ScreenPosition {
+            left: theme.label.text_offset.x,
+            top: theme.label.text_offset.y,
+        };
+
+        renderer.render_text(&self.label, text_size, *theme.label.foreground_color, *theme.label.font_size);
     }
 }
diff --git a/src/interface/elements/miscellanious/text.rs b/src/interface/elements/miscellanious/text.rs
index 58ed71f4..7f4dffbd 100644
--- a/src/interface/elements/miscellanious/text.rs
+++ b/src/interface/elements/miscellanious/text.rs
@@ -1,4 +1,3 @@
-use num::Zero;
 use procedural::dimension;
 
 use crate::graphics::{Color, InterfaceRenderer, Renderer};
@@ -78,8 +77,8 @@ impl<T: AsRef<str> + 'static> Element for Text<T> {
         _state_provider: &StateProvider,
         interface_settings: &InterfaceSettings,
         theme: &InterfaceTheme,
-        parent_position: Position,
-        clip_size: ClipSize,
+        parent_position: ScreenPosition,
+        screen_clip: ScreenClip,
         _hovered_element: Option<&dyn Element>,
         _focused_element: Option<&dyn Element>,
         _mouse_mode: &MouseInputMode,
@@ -87,7 +86,7 @@ impl<T: AsRef<str> + 'static> Element for Text<T> {
     ) {
         let mut renderer = self
             .state
-            .element_renderer(render_target, renderer, interface_settings, parent_position, clip_size);
+            .element_renderer(render_target, renderer, interface_settings, parent_position, screen_clip);
 
         let foreground_color = self
             .foreground_color
@@ -96,6 +95,11 @@ impl<T: AsRef<str> + 'static> Element for Text<T> {
             .unwrap_or(*theme.button.foreground_color);
 
         let text = self.text.as_ref().unwrap();
-        renderer.render_text(text.as_ref(), Vector2::zero(), foreground_color, self.get_font_size(theme));
+        renderer.render_text(
+            text.as_ref(),
+            ScreenPosition::default(),
+            foreground_color,
+            self.get_font_size(theme),
+        );
     }
 }
diff --git a/src/interface/elements/profiler/frame.rs b/src/interface/elements/profiler/frame.rs
index aeb43a64..10c5a7d4 100644
--- a/src/interface/elements/profiler/frame.rs
+++ b/src/interface/elements/profiler/frame.rs
@@ -52,7 +52,7 @@ impl Element for FrameView {
         None
     }
 
-    fn hovered_element(&self, mouse_position: Position, mouse_mode: &MouseInputMode) -> HoverInformation {
+    fn hovered_element(&self, mouse_position: ScreenPosition, mouse_mode: &MouseInputMode) -> HoverInformation {
         match mouse_mode {
             MouseInputMode::None => self.state.hovered_element(mouse_position),
             _ => HoverInformation::Missed,
@@ -64,8 +64,8 @@ impl Element for FrameView {
         let mouse_position = self.state.mouse_position.get();
         let number_of_frames = get_number_of_saved_frames(visible_thread);
 
-        let bar_width = self.state.cached_size.x / number_of_frames as f32;
-        let clicked_frame = (mouse_position.x / bar_width) as usize;
+        let bar_width = self.state.cached_size.width / number_of_frames as f32;
+        let clicked_frame = (mouse_position.left / bar_width) as usize;
 
         let measurement = get_frame_by_index(visible_thread, clicked_frame);
         vec![ClickAction::OpenWindow(Box::new(FrameInspectorWindow::new(measurement)))]
@@ -78,8 +78,8 @@ impl Element for FrameView {
         _state_provider: &StateProvider,
         interface_settings: &InterfaceSettings,
         _theme: &InterfaceTheme,
-        parent_position: Position,
-        clip_size: ClipSize,
+        parent_position: ScreenPosition,
+        screen_clip: ScreenClip,
         _hovered_element: Option<&dyn Element>,
         _focused_element: Option<&dyn Element>,
         _mouse_mode: &MouseInputMode,
@@ -87,39 +87,46 @@ impl Element for FrameView {
     ) {
         let mut renderer = self
             .state
-            .element_renderer(render_target, renderer, interface_settings, parent_position, clip_size);
+            .element_renderer(render_target, renderer, interface_settings, parent_position, screen_clip);
 
         let (entries, statistics_map, longest_frame) = get_statistics_data(*self.visible_thread.borrow());
 
-        let bar_width = (self.state.cached_size.x - 50.0) / entries.len() as f32;
+        let bar_width = (self.state.cached_size.width - 50.0) / entries.len() as f32;
         let gap_width = 50.0 / entries.len() as f32;
-        let height_unit = self.state.cached_size.y / longest_frame.as_secs_f32();
+        let height_unit = self.state.cached_size.height / longest_frame.as_secs_f32();
         let mut x_position = 0.0;
         let mut color_lookup = super::ColorLookup::default();
 
         for entry in entries {
-            let mut y_position = self.state.cached_size.y;
+            let mut y_position = self.state.cached_size.height;
 
             let bar_height = height_unit * entry.total_time.as_secs_f32();
+            let bar_position = ScreenPosition {
+                left: x_position,
+                top: y_position - bar_height,
+            };
+            let bar_size = ScreenSize {
+                width: bar_width,
+                height: bar_height,
+            };
 
-            renderer.render_rectangle(
-                Position::new(x_position, y_position - bar_height),
-                Size::new(bar_width, bar_height),
-                cgmath::Vector4::new(0.0, 0.0, 0.0, 0.0),
-                Color::monochrome(80),
-            );
+            renderer.render_rectangle(bar_position, bar_size, CornerRadius::default(), Color::monochrome(80));
 
             for (name, duration) in entry.frame_times {
                 let color = color_lookup.get_color(name);
                 let bar_height = height_unit * duration.as_secs_f32();
                 y_position -= bar_height;
 
-                renderer.render_rectangle(
-                    Position::new(x_position, y_position),
-                    Size::new(bar_width, bar_height),
-                    cgmath::Vector4::new(0.0, 0.0, 0.0, 0.0),
-                    color,
-                );
+                let bar_position = ScreenPosition {
+                    left: x_position,
+                    top: y_position,
+                };
+                let bar_size = ScreenSize {
+                    width: bar_width,
+                    height: bar_height,
+                };
+
+                renderer.render_rectangle(bar_position, bar_size, CornerRadius::default(), color);
             }
 
             x_position += bar_width + gap_width;
@@ -130,10 +137,16 @@ impl Element for FrameView {
             let statistics = statistics_map.get(name).unwrap();
             let text = format!("{} {:?} (SD {:.1})", name, statistics.mean, statistics.standard_deviation);
 
+            let text_position = ScreenPosition {
+                left: 3.0,
+                top: y_position,
+            };
+            let shadow_position = text_position + ScreenSize::uniform(1.0);
+
             // Drop shadow.
-            renderer.render_text(&text, Position::new(4.0, y_position + 1.0), Color::monochrome(0), 14.0);
+            renderer.render_text(&text, shadow_position, Color::monochrome(0), 14.0);
             // Colored text.
-            renderer.render_text(&text, Position::new(3.0, y_position), color, 14.0);
+            renderer.render_text(&text, text_position, color, 14.0);
 
             y_position += 14.0;
         }
diff --git a/src/interface/elements/profiler/inspector.rs b/src/interface/elements/profiler/inspector.rs
index cfcaf9eb..37104267 100644
--- a/src/interface/elements/profiler/inspector.rs
+++ b/src/interface/elements/profiler/inspector.rs
@@ -1,6 +1,5 @@
 use std::time::{Duration, Instant};
 
-use cgmath::{Vector4, Zero};
 use procedural::*;
 
 use crate::debug::*;
@@ -45,31 +44,35 @@ impl FrameInspectorView {
         text_width: f32,
         mut x_position: f32,
         distance: f32,
-        size: Size,
+        size: ScreenSize,
         alpha: f32,
         render_numbers: bool,
     ) {
         let color = theme.profiler.line_color.multiply_alpha_f32(alpha);
 
-        while x_position < size.x {
-            renderer.render_rectangle(
-                Position::new(x_position, 0.0),
-                Size::new(*theme.profiler.line_width * *renderer.interface_settings.scaling, size.y),
-                Vector4::zero(),
-                color,
-            );
+        while x_position < size.width {
+            let line_position = ScreenPosition {
+                left: x_position,
+                top: 0.0,
+            };
+            let line_size = ScreenSize {
+                width: *theme.profiler.line_width * *renderer.interface_settings.scaling,
+                height: size.height,
+            };
+
+            renderer.render_rectangle(line_position, line_size, CornerRadius::default(), color);
 
             if render_numbers {
-                let offset = Position::new(
-                    x_position + (distance - text_width) / 2.0,
-                    size.y - *theme.profiler.distance_text_offset * *renderer.interface_settings.scaling,
-                );
+                let offset = ScreenPosition {
+                    left: x_position + (distance - text_width) / 2.0,
+                    top: size.height - *theme.profiler.distance_text_offset * *renderer.interface_settings.scaling,
+                };
 
                 renderer.renderer.render_text(
                     renderer.render_target,
                     text,
                     renderer.position + offset,
-                    renderer.clip_size,
+                    renderer.screen_clip,
                     *theme.profiler.line_color,
                     *theme.profiler.distance_text_size * *renderer.interface_settings.scaling,
                 );
@@ -96,7 +99,10 @@ impl FrameInspectorView {
 
         let scaled_bar_gap = theme.profiler.bar_gap.x * *renderer.interface_settings.scaling;
         let color = color_lookup.get_color(measurement.name);
-        let text_offset = *theme.profiler.bar_text_offset * *renderer.interface_settings.scaling;
+        let text_offset = ScreenPosition {
+            left: theme.profiler.bar_text_offset.x * *renderer.interface_settings.scaling,
+            top: theme.profiler.bar_text_offset.y * *renderer.interface_settings.scaling,
+        };
         let x_position = measurement.start_time.saturating_duration_since(start_time).as_secs_f32() * unit + scaled_bar_gap;
         let x_size = measurement.end_time.saturating_duration_since(start_time).as_secs_f32() * unit - x_position - scaled_bar_gap;
         let x_size = x_size.min(total_width - x_position - scaled_bar_gap);
@@ -107,10 +113,19 @@ impl FrameInspectorView {
             return;
         }
 
+        let block_position = ScreenPosition {
+            left: x_position,
+            top: y_position,
+        };
+        let block_size = ScreenSize {
+            width: x_size,
+            height: y_size,
+        };
+
         renderer.render_rectangle(
-            Position::new(x_position, y_position),
-            Size::new(x_size, y_size),
-            *theme.profiler.bar_border_radius,
+            block_position,
+            block_size,
+            (*theme.profiler.bar_corner_radius).into(),
             color.multiply_alpha_f32(alpha),
         );
 
@@ -122,18 +137,25 @@ impl FrameInspectorView {
 
         if alpha > VISIBILITY_THRESHHOLD {
             let text = format!("{} ({:?})", measurement.name, measurement.end_time - measurement.start_time);
-            let clip_size = ClipSize::new(
-                renderer.clip_size.x + x_position,
-                renderer.clip_size.y + y_position,
-                renderer.clip_size.x + x_position + x_size,
-                renderer.clip_size.y + y_position + y_size,
-            );
+            let screen_clip = ScreenClip {
+                left: renderer.screen_clip.left + x_position,
+                top: renderer.screen_clip.top + y_position,
+                right: renderer.screen_clip.left + x_position + x_size,
+                bottom: renderer.screen_clip.top + y_position + y_size,
+            };
+
+            let text_position = renderer.position
+                + ScreenPosition {
+                    left: x_position,
+                    top: y_position,
+                }
+                + text_offset;
 
             renderer.renderer.render_text(
                 renderer.render_target,
                 &text,
-                renderer.position + Position::new(x_position, y_position) + text_offset,
-                clip_size,
+                text_position,
+                screen_clip,
                 theme.profiler.bar_text_color.multiply_alpha_f32(alpha),
                 *theme.profiler.bar_text_size * *renderer.interface_settings.scaling,
             );
@@ -173,7 +195,7 @@ impl Element for FrameInspectorView {
         self.state.resolve(placement_resolver, size_constraint);
     }
 
-    fn hovered_element(&self, mouse_position: Position, mouse_mode: &MouseInputMode) -> HoverInformation {
+    fn hovered_element(&self, mouse_position: ScreenPosition, mouse_mode: &MouseInputMode) -> HoverInformation {
         match mouse_mode {
             MouseInputMode::None => self.state.hovered_element(mouse_position),
             _ => HoverInformation::Missed,
@@ -184,7 +206,7 @@ impl Element for FrameInspectorView {
         const ZOOM_SPEED: f32 = 0.004;
 
         let viewed_duration = self.measurement.total_time_taken() - (self.start_offset + self.end_offset);
-        let side_bias = (1.0 / self.state.cached_size.x) * self.state.mouse_position.get().x;
+        let side_bias = (1.0 / self.state.cached_size.width) * self.state.mouse_position.get().left;
         let total_offset = viewed_duration.mul_f32(delta.abs() * ZOOM_SPEED);
 
         if delta.is_sign_negative() {
@@ -205,8 +227,8 @@ impl Element for FrameInspectorView {
         _state_provider: &StateProvider,
         interface_settings: &InterfaceSettings,
         theme: &InterfaceTheme,
-        parent_position: Position,
-        clip_size: ClipSize,
+        parent_position: ScreenPosition,
+        screen_clip: ScreenClip,
         _hovered_element: Option<&dyn Element>,
         _focused_element: Option<&dyn Element>,
         _mouse_mode: &MouseInputMode,
@@ -218,9 +240,9 @@ impl Element for FrameInspectorView {
 
         let mut renderer = self
             .state
-            .element_renderer(render_target, renderer, interface_settings, parent_position, clip_size);
+            .element_renderer(render_target, renderer, interface_settings, parent_position, screen_clip);
 
-        renderer.render_background(*theme.profiler.border_radius, *theme.profiler.background_color);
+        renderer.render_background((*theme.profiler.corner_radius).into(), *theme.profiler.background_color);
 
         let mut colors = super::ColorLookup::default();
 
@@ -240,7 +262,7 @@ impl Element for FrameInspectorView {
                 let visibility = Self::interpolate_alpha_smoothed($max, $min, viewed_duration.$alpha_function() as f32);
 
                 if visibility > VISIBILITY_THRESHHOLD {
-                    let distance = $duration.div_duration_f32(viewed_duration) * self.state.cached_size.x;
+                    let distance = $duration.div_duration_f32(viewed_duration) * self.state.cached_size.width;
                     let offset = ((self.start_offset.$div_function() as f32 / $divider) * -distance) % distance;
 
                     let text_width = renderer
@@ -283,8 +305,8 @@ impl Element for FrameInspectorView {
             theme,
             &self.measurement,
             start_time,
-            self.state.cached_size.x,
-            self.state.cached_size.x / viewed_duration.as_secs_f32(),
+            self.state.cached_size.width,
+            self.state.cached_size.width / viewed_duration.as_secs_f32(),
             theme.profiler.bar_gap.y * *interface_settings.scaling,
         );
     }
diff --git a/src/interface/elements/values/color.rs b/src/interface/elements/values/color.rs
index ab424f84..39e2c99c 100644
--- a/src/interface/elements/values/color.rs
+++ b/src/interface/elements/values/color.rs
@@ -36,8 +36,8 @@ impl Element for ColorValue {
         _state_provider: &StateProvider,
         interface_settings: &InterfaceSettings,
         theme: &InterfaceTheme,
-        parent_position: Position,
-        clip_size: ClipSize,
+        parent_position: ScreenPosition,
+        screen_clip: ScreenClip,
         _hovered_element: Option<&dyn Element>,
         _focused_element: Option<&dyn Element>,
         _mouse_mode: &MouseInputMode,
@@ -45,15 +45,15 @@ impl Element for ColorValue {
     ) {
         let mut renderer = self
             .state
-            .element_renderer(render_target, renderer, interface_settings, parent_position, clip_size);
+            .element_renderer(render_target, renderer, interface_settings, parent_position, screen_clip);
 
-        renderer.render_background(*theme.value.border_radius, self.color);
+        renderer.render_background((*theme.value.corner_radius).into(), self.color);
 
-        renderer.render_text(
-            &self.display,
-            *theme.value.text_offset,
-            self.color.invert(),
-            *theme.value.font_size,
-        );
+        let text_position = ScreenPosition {
+            left: theme.value.text_offset.x,
+            top: theme.value.text_offset.y,
+        };
+
+        renderer.render_text(&self.display, text_position, self.color.invert(), *theme.value.font_size);
     }
 }
diff --git a/src/interface/elements/values/mutable/color.rs b/src/interface/elements/values/mutable/color.rs
index c04f323c..3099c5ba 100644
--- a/src/interface/elements/values/mutable/color.rs
+++ b/src/interface/elements/values/mutable/color.rs
@@ -59,7 +59,7 @@ impl Element for MutableColorValue {
         None
     }
 
-    fn hovered_element(&self, mouse_position: Position, mouse_mode: &MouseInputMode) -> HoverInformation {
+    fn hovered_element(&self, mouse_position: ScreenPosition, mouse_mode: &MouseInputMode) -> HoverInformation {
         match mouse_mode {
             MouseInputMode::None => self.state.hovered_element(mouse_position),
             _ => HoverInformation::Missed,
@@ -81,8 +81,8 @@ impl Element for MutableColorValue {
         _state_provider: &StateProvider,
         interface_settings: &InterfaceSettings,
         theme: &InterfaceTheme,
-        parent_position: Position,
-        clip_size: ClipSize,
+        parent_position: ScreenPosition,
+        screen_clip: ScreenClip,
         hovered_element: Option<&dyn Element>,
         _focused_element: Option<&dyn Element>,
         _mouse_mode: &MouseInputMode,
@@ -90,18 +90,23 @@ impl Element for MutableColorValue {
     ) {
         let mut renderer = self
             .state
-            .element_renderer(render_target, renderer, interface_settings, parent_position, clip_size);
+            .element_renderer(render_target, renderer, interface_settings, parent_position, screen_clip);
 
         let background_color = match self.is_element_self(hovered_element) {
             true => self.cached_color.shade(),
             false => self.cached_color,
         };
 
-        renderer.render_background(*theme.value.border_radius, background_color);
+        renderer.render_background((*theme.value.corner_radius).into(), background_color);
+
+        let text_position = ScreenPosition {
+            left: theme.value.text_offset.x,
+            top: theme.value.text_offset.y,
+        };
 
         renderer.render_text(
             &self.cached_values,
-            *theme.value.text_offset,
+            text_position,
             self.cached_color.invert(),
             *theme.value.font_size,
         );
diff --git a/src/interface/elements/values/mutable/number.rs b/src/interface/elements/values/mutable/number.rs
index f17c6005..4234d858 100644
--- a/src/interface/elements/values/mutable/number.rs
+++ b/src/interface/elements/values/mutable/number.rs
@@ -63,7 +63,7 @@ impl<T: Zero + NumOps + NumCast + Copy + PartialOrd + Display + 'static> Element
         None
     }
 
-    fn hovered_element(&self, mouse_position: Position, mouse_mode: &MouseInputMode) -> HoverInformation {
+    fn hovered_element(&self, mouse_position: ScreenPosition, mouse_mode: &MouseInputMode) -> HoverInformation {
         match mouse_mode {
             MouseInputMode::None => self.state.hovered_element(mouse_position),
             _ => HoverInformation::Missed,
@@ -87,8 +87,8 @@ impl<T: Zero + NumOps + NumCast + Copy + PartialOrd + Display + 'static> Element
         _state_provider: &StateProvider,
         interface_settings: &InterfaceSettings,
         theme: &InterfaceTheme,
-        parent_position: Position,
-        clip_size: ClipSize,
+        parent_position: ScreenPosition,
+        screen_clip: ScreenClip,
         hovered_element: Option<&dyn Element>,
         _focused_element: Option<&dyn Element>,
         _mouse_mode: &MouseInputMode,
@@ -96,18 +96,23 @@ impl<T: Zero + NumOps + NumCast + Copy + PartialOrd + Display + 'static> Element
     ) {
         let mut renderer = self
             .state
-            .element_renderer(render_target, renderer, interface_settings, parent_position, clip_size);
+            .element_renderer(render_target, renderer, interface_settings, parent_position, screen_clip);
 
         let background_color = match self.is_element_self(hovered_element) {
             true => *theme.value.hovered_background_color,
             false => *theme.value.background_color,
         };
 
-        renderer.render_background(*theme.value.border_radius, background_color);
+        renderer.render_background((*theme.value.corner_radius).into(), background_color);
+
+        let text_position = ScreenPosition {
+            left: theme.value.text_offset.x,
+            top: theme.value.text_offset.y,
+        };
 
         renderer.render_text(
             &self.cached_values,
-            *theme.value.text_offset,
+            text_position,
             *theme.value.foreground_color,
             *theme.value.font_size,
         );
diff --git a/src/interface/elements/values/mutable/vector.rs b/src/interface/elements/values/mutable/vector.rs
index c56ea7f4..a4cff54c 100644
--- a/src/interface/elements/values/mutable/vector.rs
+++ b/src/interface/elements/values/mutable/vector.rs
@@ -76,7 +76,7 @@ where
         None
     }
 
-    fn hovered_element(&self, mouse_position: Position, mouse_mode: &MouseInputMode) -> HoverInformation {
+    fn hovered_element(&self, mouse_position: ScreenPosition, mouse_mode: &MouseInputMode) -> HoverInformation {
         match mouse_mode {
             MouseInputMode::None => self.state.hovered_element(mouse_position),
             _ => HoverInformation::Missed,
@@ -102,8 +102,8 @@ where
         _state_provider: &StateProvider,
         interface_settings: &InterfaceSettings,
         theme: &InterfaceTheme,
-        parent_position: Position,
-        clip_size: ClipSize,
+        parent_position: ScreenPosition,
+        screen_clip: ScreenClip,
         hovered_element: Option<&dyn Element>,
         _focused_element: Option<&dyn Element>,
         _mouse_mode: &MouseInputMode,
@@ -111,18 +111,23 @@ where
     ) {
         let mut renderer = self
             .state
-            .element_renderer(render_target, renderer, interface_settings, parent_position, clip_size);
+            .element_renderer(render_target, renderer, interface_settings, parent_position, screen_clip);
 
         let background_color = match self.is_element_self(hovered_element) {
             true => *theme.value.hovered_background_color,
             false => *theme.value.background_color,
         };
 
-        renderer.render_background(*theme.value.border_radius, background_color);
+        renderer.render_background((*theme.value.corner_radius).into(), background_color);
+
+        let text_position = ScreenPosition {
+            left: theme.value.text_offset.x,
+            top: theme.value.text_offset.y,
+        };
 
         renderer.render_text(
             &self.cached_values,
-            *theme.value.text_offset,
+            text_position,
             *theme.value.foreground_color,
             *theme.value.font_size,
         );
diff --git a/src/interface/elements/values/quaternion.rs b/src/interface/elements/values/quaternion.rs
index 3d433b34..03bcfe8c 100644
--- a/src/interface/elements/values/quaternion.rs
+++ b/src/interface/elements/values/quaternion.rs
@@ -47,7 +47,7 @@ impl<T: Display> Element for QuaternionValue<T> {
         interface_settings: &InterfaceSettings,
         theme: &Theme,
         parent_position: Position,
-        clip_size: ClipSize,
+        screen_clip: ClipSize,
         _hovered_element: Option<&dyn Element>,
         _focused_element: Option<&dyn Element>,
         _second_theme: bool,
@@ -55,9 +55,9 @@ impl<T: Display> Element for QuaternionValue<T> {
 
         let mut renderer = self
             .state
-            .element_renderer(render_target, renderer, interface_settings, parent_position, clip_size);
+            .element_renderer(render_target, renderer, interface_settings, parent_position, screen_clip);
 
-        renderer.render_background(*theme.value.border_radius, *theme.value.hovered_background_color);
+        renderer.render_background(*theme.value.corner_radius, *theme.value.hovered_background_color);
 
         renderer.render_text(
             &self.display,
diff --git a/src/interface/elements/values/string.rs b/src/interface/elements/values/string.rs
index 021f74b3..75e80809 100644
--- a/src/interface/elements/values/string.rs
+++ b/src/interface/elements/values/string.rs
@@ -30,8 +30,8 @@ impl Element for StringValue {
         _state_provider: &StateProvider,
         interface_settings: &InterfaceSettings,
         theme: &InterfaceTheme,
-        parent_position: Position,
-        clip_size: ClipSize,
+        parent_position: ScreenPosition,
+        screen_clip: ScreenClip,
         _hovered_element: Option<&dyn Element>,
         _focused_element: Option<&dyn Element>,
         _mouse_mode: &MouseInputMode,
@@ -39,13 +39,18 @@ impl Element for StringValue {
     ) {
         let mut renderer = self
             .state
-            .element_renderer(render_target, renderer, interface_settings, parent_position, clip_size);
+            .element_renderer(render_target, renderer, interface_settings, parent_position, screen_clip);
 
-        renderer.render_background(*theme.value.border_radius, *theme.value.hovered_background_color);
+        renderer.render_background((*theme.value.corner_radius).into(), *theme.value.hovered_background_color);
+
+        let text_position = ScreenPosition {
+            left: theme.value.text_offset.x,
+            top: theme.value.text_offset.y,
+        };
 
         renderer.render_text(
             &self.value,
-            *theme.value.text_offset,
+            text_position,
             *theme.value.foreground_color,
             *theme.value.font_size,
         );
diff --git a/src/interface/elements/values/vector.rs b/src/interface/elements/values/vector.rs
index 24ae68e9..4e95dde7 100644
--- a/src/interface/elements/values/vector.rs
+++ b/src/interface/elements/values/vector.rs
@@ -61,7 +61,7 @@ where
         interface_settings: &InterfaceSettings,
         theme: &Theme,
         parent_position: Position,
-        clip_size: ClipSize,
+        screen_clip: ClipSize,
         _hovered_element: Option<&dyn Element>,
         _focused_element: Option<&dyn Element>,
         _second_theme: bool,
@@ -69,9 +69,9 @@ where
 
         let mut renderer = self
             .state
-            .element_renderer(render_target, renderer, interface_settings, parent_position, clip_size);
+            .element_renderer(render_target, renderer, interface_settings, parent_position, screen_clip);
 
-        renderer.render_background(*theme.value.border_radius, *theme.value.hovered_background_color);
+        renderer.render_background(*theme.value.corner_radius, *theme.value.hovered_background_color);
 
         renderer.render_text(
             &self.display,
diff --git a/src/interface/event/action.rs b/src/interface/event/action.rs
index 8f7d1526..7e33a7e8 100644
--- a/src/interface/event/action.rs
+++ b/src/interface/event/action.rs
@@ -1,6 +1,6 @@
 use super::{ItemSource, SkillSource};
 use crate::input::UserEvent;
-use crate::interface::{ChangeEvent, ElementCell, FocusMode, Position, PrototypeWindow, Size, Tracker};
+use crate::interface::{ChangeEvent, ElementCell, FocusMode, PrototypeWindow, ScreenPosition, ScreenSize, Tracker};
 use crate::inventory::{Item, Skill};
 
 pub enum ClickAction {
@@ -16,8 +16,8 @@ pub enum ClickAction {
     CloseWindow,
     OpenPopup {
         element: ElementCell,
-        position_tracker: Tracker<Position>,
-        size_tracker: Tracker<Size>,
+        position_tracker: Tracker<ScreenPosition>,
+        size_tracker: Tracker<ScreenSize>,
     },
     ClosePopup,
 }
diff --git a/src/interface/layout/constraint.rs b/src/interface/layout/constraint.rs
index 93ab7bd8..388f8b93 100644
--- a/src/interface/layout/constraint.rs
+++ b/src/interface/layout/constraint.rs
@@ -2,7 +2,7 @@ use derive_new::new;
 use procedural::constraint;
 use serde::{Deserialize, Serialize};
 
-use crate::interface::{Dimension, PartialSize, Position, Size};
+use crate::interface::{Dimension, PartialScreenSize, ScreenPosition, ScreenSize};
 
 #[derive(Copy, Clone, Serialize, Deserialize, new)]
 pub struct DimensionConstraint {
@@ -35,28 +35,30 @@ pub struct SizeConstraint {
 }
 
 impl SizeConstraint {
-    pub fn resolve(&self, available: Size, remaining: Size, scaling: f32) -> PartialSize {
-        let width = self.width.resolve_width(available.x, remaining.x, scaling);
-        let width = self.validated_width(width, available.x, remaining.x, scaling);
+    pub fn resolve(&self, available: ScreenSize, remaining: ScreenSize, scaling: f32) -> PartialScreenSize {
+        let width = self.width.resolve_width(available.width, remaining.width, scaling);
+        let width = self.validated_width(width, available.width, remaining.width, scaling);
 
-        let mut height = self.height.resolve_height(available.y.into(), remaining.y.into(), scaling);
+        let mut height = self
+            .height
+            .resolve_height(available.height.into(), remaining.height.into(), scaling);
         if let Some(height) = &mut height {
-            *height = self.validated_height(*height, available.y.into(), remaining.y.into(), scaling);
+            *height = self.validated_height(*height, available.height.into(), remaining.height.into(), scaling);
         }
 
-        PartialSize::new(width, height)
+        PartialScreenSize::new(width, height)
     }
 
-    pub fn resolve_partial(&self, available: PartialSize, remaining: PartialSize, scaling: f32) -> PartialSize {
-        let width = self.width.resolve_width(available.x, remaining.x, scaling);
-        let width = self.validated_width(width, available.x, remaining.x, scaling);
+    pub fn resolve_partial(&self, available: PartialScreenSize, remaining: PartialScreenSize, scaling: f32) -> PartialScreenSize {
+        let width = self.width.resolve_width(available.width, remaining.width, scaling);
+        let width = self.validated_width(width, available.width, remaining.width, scaling);
 
-        let mut height = self.height.resolve_height(available.y, remaining.y, scaling);
+        let mut height = self.height.resolve_height(available.height, remaining.height, scaling);
         if let Some(height) = &mut height {
-            *height = self.validated_height(*height, available.y, remaining.y, scaling);
+            *height = self.validated_height(*height, available.height, remaining.height, scaling);
         }
 
-        PartialSize::new(width, height)
+        PartialScreenSize::new(width, height)
     }
 
     fn validated_width(&self, mut width: f32, available: f32, remaining: f32, scaling: f32) -> f32 {
@@ -87,17 +89,19 @@ impl SizeConstraint {
         height
     }
 
-    pub fn validated_size(&self, size: Size, available: Size, scaling: f32) -> Size {
-        let width = self.validated_width(size.x, available.x, available.x, scaling);
-        let height = self.validated_height(size.y, available.y.into(), available.y.into(), scaling);
-        Size::new(width, height)
+    pub fn validated_size(&self, size: ScreenSize, available: ScreenSize, scaling: f32) -> ScreenSize {
+        let width = self.validated_width(size.width, available.width, available.width, scaling);
+        let height = self.validated_height(size.height, available.height.into(), available.height.into(), scaling);
+
+        ScreenSize { width, height }
     }
 
-    pub fn validated_position(&self, position: Position, size: Size, available: Size) -> Position {
+    pub fn validated_position(&self, position: ScreenPosition, size: ScreenSize, available: ScreenSize) -> ScreenPosition {
         let half_size = size / 2.0;
-        let x = f32::clamp(position.x, -half_size.x, available.x - half_size.x);
-        let y = f32::clamp(position.y, 0.0, available.y - 30.0);
-        Position::new(x, y)
+        let left = f32::clamp(position.left, -half_size.width, available.width - half_size.width);
+        let top = f32::clamp(position.top, 0.0, available.height - 30.0);
+
+        ScreenPosition { left, top }
     }
 }
 
diff --git a/src/interface/layout/mod.rs b/src/interface/layout/mod.rs
index f83254ba..1803428c 100644
--- a/src/interface/layout/mod.rs
+++ b/src/interface/layout/mod.rs
@@ -6,4 +6,4 @@ mod size;
 pub use self::constraint::{DimensionConstraint, SizeConstraint};
 pub use self::dimension::Dimension;
 pub use self::resolver::PlacementResolver;
-pub use self::size::{ClipSize, PartialSize, Position, Size};
+pub use self::size::{CornerRadius, PartialScreenSize, ScreenClip, ScreenPosition, ScreenSize};
diff --git a/src/interface/layout/resolver.rs b/src/interface/layout/resolver.rs
index 8a4b33bd..773c2e6d 100644
--- a/src/interface/layout/resolver.rs
+++ b/src/interface/layout/resolver.rs
@@ -3,7 +3,7 @@ use std::rc::Rc;
 
 use cgmath::Vector2;
 
-use crate::interface::{PartialSize, Position, Size, SizeConstraint};
+use crate::interface::{PartialScreenSize, ScreenPosition, ScreenSize, SizeConstraint};
 use crate::loaders::FontLoader;
 
 const ELEMENT_THRESHHOLD: f32 = 1.0000;
@@ -11,22 +11,28 @@ const REMAINDER_THRESHHOLD: f32 = 0.0001;
 
 pub struct PlacementResolver {
     font_loader: Rc<RefCell<FontLoader>>,
-    available_space: PartialSize,
-    base_position: Position,
+    available_space: PartialScreenSize,
+    base_position: ScreenPosition,
     horizontal_accumulator: f32,
     vertical_offset: f32,
     total_height: f32,
-    border: Size,
-    gaps: Size,
+    border: ScreenSize,
+    gaps: ScreenSize,
     scaling: f32,
 }
 
 impl PlacementResolver {
-    pub fn new(font_loader: Rc<RefCell<FontLoader>>, mut available_space: PartialSize, border: Size, gaps: Size, scaling: f32) -> Self {
-        available_space.x -= border.x * scaling * 2.0;
-        available_space.y = available_space.y.map(|height| height - border.y * scaling * 2.0);
+    pub fn new(
+        font_loader: Rc<RefCell<FontLoader>>,
+        mut available_space: PartialScreenSize,
+        border: ScreenSize,
+        gaps: ScreenSize,
+        scaling: f32,
+    ) -> Self {
+        available_space.width -= border.width * scaling * 2.0;
+        available_space.height = available_space.height.map(|height| height - border.height * scaling * 2.0);
 
-        let base_position = border * scaling;
+        let base_position = ScreenPosition::from_size(border * scaling);
         let horizontal_accumulator = 0.0;
         let vertical_offset = 0.0;
         let total_height = 0.0;
@@ -44,9 +50,9 @@ impl PlacementResolver {
         }
     }
 
-    pub fn derive(&self, mut available_space: PartialSize, offset: Position, border: Size) -> Self {
-        available_space.x -= offset.x + border.x * self.scaling * 2.0;
-        available_space.y = available_space.y.map(|height| height - border.y * self.scaling * 2.0);
+    pub fn derive(&self, mut available_space: PartialScreenSize, offset: ScreenPosition, border: ScreenSize) -> Self {
+        available_space.width -= offset.left + border.width * self.scaling * 2.0;
+        available_space.height = available_space.height.map(|height| height - border.height * self.scaling * 2.0);
 
         let font_loader = self.font_loader.clone();
         let base_position = offset + border * self.scaling;
@@ -82,27 +88,27 @@ impl PlacementResolver {
             .get_text_dimensions(text, font_size * scaling, available_width - text_offset.x * scaling)
     }
 
-    pub fn set_gaps(&mut self, gaps: Size) {
+    pub fn set_gaps(&mut self, gaps: ScreenSize) {
         self.gaps = gaps;
     }
 
-    pub fn get_available(&self) -> PartialSize {
+    pub fn get_available(&self) -> PartialScreenSize {
         self.available_space
     }
 
-    pub fn get_remaining(&self) -> PartialSize {
-        let remaining_width = self.available_space.x - self.horizontal_accumulator;
+    pub fn get_remaining(&self) -> PartialScreenSize {
+        let remaining_width = self.available_space.width - self.horizontal_accumulator;
         let remaining_height = self
             .available_space
-            .y
+            .height
             .map(|height| height - self.total_height - self.vertical_offset);
 
-        PartialSize::new(remaining_width, remaining_height)
+        PartialScreenSize::new(remaining_width, remaining_height)
     }
 
     pub fn newline(&mut self) {
-        self.total_height += self.vertical_offset + self.gaps.y * self.scaling;
-        self.base_position.y += self.vertical_offset + self.gaps.y * self.scaling;
+        self.total_height += self.vertical_offset + self.gaps.height * self.scaling;
+        self.base_position.top += self.vertical_offset + self.gaps.height * self.scaling;
         self.horizontal_accumulator = 0.0;
         self.vertical_offset = 0.0;
     }
@@ -111,10 +117,10 @@ impl PlacementResolver {
         self.vertical_offset = f32::max(self.vertical_offset, height);
     }
 
-    pub fn allocate(&mut self, size_constraint: &SizeConstraint) -> (PartialSize, Position) {
+    pub fn allocate(&mut self, size_constraint: &SizeConstraint) -> (PartialScreenSize, ScreenPosition) {
         let is_width_absolute = size_constraint.width.is_absolute();
         let gaps_add = match is_width_absolute {
-            true => self.gaps.x * 2.0,
+            true => self.gaps.width * 2.0,
             false => 0.0,
         };
 
@@ -122,7 +128,7 @@ impl PlacementResolver {
         let mut size = size_constraint.resolve_partial(self.available_space, remaining, self.scaling);
         let mut gaps_subtract = 0.0;
 
-        if remaining.x < size.x - REMAINDER_THRESHHOLD {
+        if remaining.width < size.width - REMAINDER_THRESHHOLD {
             self.newline();
             remaining = self.get_remaining();
 
@@ -130,43 +136,43 @@ impl PlacementResolver {
                 size = size_constraint.resolve_partial(self.available_space, remaining, self.scaling);
             }
 
-            size.x = f32::min(size.x, self.available_space.x);
+            size.width = f32::min(size.width, self.available_space.width);
         }
 
         if self.horizontal_accumulator > ELEMENT_THRESHHOLD {
             match is_width_absolute {
                 true => {}
-                false => gaps_subtract += self.gaps.x * self.scaling,
+                false => gaps_subtract += self.gaps.width * self.scaling,
             }
         }
 
-        let position = Vector2::new(
-            self.base_position.x + self.horizontal_accumulator + gaps_subtract,
-            self.base_position.y,
-        );
+        let position = ScreenPosition {
+            left: self.base_position.left + self.horizontal_accumulator + gaps_subtract,
+            top: self.base_position.top,
+        };
 
-        self.horizontal_accumulator += size.x + gaps_add;
+        self.horizontal_accumulator += size.width + gaps_add;
 
-        if let Some(height) = size.y {
+        if let Some(height) = size.height {
             self.register_height(height);
         }
 
-        if remaining.x - size.x > ELEMENT_THRESHHOLD {
+        if remaining.width - size.width > ELEMENT_THRESHHOLD {
             match is_width_absolute {
                 true => {}
-                false => gaps_subtract += self.gaps.x * self.scaling,
+                false => gaps_subtract += self.gaps.width * self.scaling,
             }
         }
 
-        size.x -= gaps_subtract;
+        size.width -= gaps_subtract;
         (size, position)
     }
 
-    pub fn allocate_right(&mut self, size_constraint: &SizeConstraint) -> (PartialSize, Position) {
+    pub fn allocate_right(&mut self, size_constraint: &SizeConstraint) -> (PartialScreenSize, ScreenPosition) {
         let mut remaining = self.get_remaining();
         let mut size = size_constraint.resolve_partial(self.available_space, remaining, self.scaling);
 
-        if remaining.x < size.x - REMAINDER_THRESHHOLD + self.gaps.x * self.scaling {
+        if remaining.width < size.width - REMAINDER_THRESHHOLD + self.gaps.width * self.scaling {
             self.newline();
             remaining = self.get_remaining();
 
@@ -175,14 +181,14 @@ impl PlacementResolver {
             }
         }
 
-        let position = Vector2::new(
-            self.base_position.x + (self.available_space.x - size.x - self.gaps.x * self.scaling),
-            self.base_position.y,
-        );
+        let position = ScreenPosition {
+            left: self.base_position.left + (self.available_space.width - size.width - self.gaps.width * self.scaling),
+            top: self.base_position.top,
+        };
 
-        self.horizontal_accumulator += remaining.x;
+        self.horizontal_accumulator += remaining.width;
 
-        if let Some(height) = size.y {
+        if let Some(height) = size.height {
             self.register_height(height);
         }
 
@@ -190,6 +196,6 @@ impl PlacementResolver {
     }
 
     pub fn final_height(self) -> f32 {
-        self.total_height + self.vertical_offset + self.border.y * self.scaling
+        self.total_height + self.vertical_offset + self.border.height * self.scaling
     }
 }
diff --git a/src/interface/layout/size.rs b/src/interface/layout/size.rs
index 7e62846b..e2ebb22b 100644
--- a/src/interface/layout/size.rs
+++ b/src/interface/layout/size.rs
@@ -1,35 +1,278 @@
-use cgmath::{Vector2, Vector4};
 use derive_new::new;
+use serde::{Deserialize, Serialize};
 
-pub type Size = Vector2<f32>;
-pub type ClipSize = Vector4<f32>;
-pub type Position = Vector2<f32>;
+macro_rules! implement_ops {
+    ($name:ident, $x:ident, $y:ident) => {
+        impl $name {
+            pub fn uniform(value: f32) -> Self {
+                Self { $x: value, $y: value }
+            }
+        }
+
+        impl std::ops::AddAssign<$name> for $name {
+            fn add_assign(&mut self, rhs: Self) {
+                self.$x += rhs.$x;
+                self.$y += rhs.$y;
+            }
+        }
+
+        impl std::ops::SubAssign<$name> for $name {
+            fn sub_assign(&mut self, rhs: Self) {
+                self.$x -= rhs.$x;
+                self.$y -= rhs.$y;
+            }
+        }
+
+        impl std::ops::Add<$name> for $name {
+            type Output = Self;
+
+            fn add(self, rhs: Self) -> Self {
+                Self {
+                    $x: self.$x + rhs.$x,
+                    $y: self.$y + rhs.$y,
+                }
+            }
+        }
+
+        impl std::ops::Div<f32> for $name {
+            type Output = Self;
+
+            fn div(self, rhs: f32) -> Self {
+                Self {
+                    $x: self.$x / rhs,
+                    $y: self.$y / rhs,
+                }
+            }
+        }
+
+        impl std::ops::Div<ScreenSize> for $name {
+            type Output = Self;
+
+            fn div(self, rhs: ScreenSize) -> Self {
+                Self {
+                    $x: self.$x / rhs.width,
+                    $y: self.$y / rhs.height,
+                }
+            }
+        }
+
+        impl std::ops::Mul<f32> for $name {
+            type Output = Self;
+
+            fn mul(self, rhs: f32) -> Self {
+                Self {
+                    $x: self.$x * rhs,
+                    $y: self.$y * rhs,
+                }
+            }
+        }
+
+        impl From<$name> for [f32; 2] {
+            fn from(value: $name) -> Self {
+                [value.$x, value.$y]
+            }
+        }
+    };
+}
+
+/// The position as seen on screen.
+#[derive(Debug, Clone, Copy, Default, PartialEq, Serialize, Deserialize)]
+pub struct ScreenPosition {
+    pub left: f32,
+    pub top: f32,
+}
+
+impl ScreenPosition {
+    pub fn from_size(ScreenSize { width, height }: ScreenSize) -> Self {
+        Self { left: width, top: height }
+    }
+
+    pub fn only_top(top: f32) -> Self {
+        Self { left: 0.0, top }
+    }
+}
+
+implement_ops!(ScreenPosition, left, top);
+
+impl std::ops::Sub<ScreenPosition> for ScreenPosition {
+    type Output = ScreenSize;
+
+    fn sub(self, rhs: ScreenPosition) -> ScreenSize {
+        ScreenSize {
+            width: self.left - rhs.left,
+            height: self.top - rhs.top,
+        }
+    }
+}
+
+impl std::ops::AddAssign<ScreenSize> for ScreenPosition {
+    fn add_assign(&mut self, rhs: ScreenSize) {
+        self.left += rhs.width;
+        self.top += rhs.height;
+    }
+}
+
+/// The size as seen on screen.
+#[derive(Debug, Clone, Copy, Default, PartialEq, Serialize, Deserialize)]
+pub struct ScreenSize {
+    pub width: f32,
+    pub height: f32,
+}
+
+impl ScreenSize {
+    pub fn only_width(width: f32) -> Self {
+        Self { width, height: 0.0 }
+    }
+}
+
+implement_ops!(ScreenSize, width, height);
+
+impl std::ops::Sub<ScreenSize> for ScreenSize {
+    type Output = Self;
+
+    fn sub(self, rhs: ScreenSize) -> Self {
+        Self {
+            width: self.width - rhs.width,
+            height: self.height - rhs.height,
+        }
+    }
+}
+
+impl std::ops::Add<ScreenPosition> for ScreenSize {
+    type Output = ScreenPosition;
+
+    fn add(self, rhs: ScreenPosition) -> ScreenPosition {
+        ScreenPosition {
+            left: self.width + rhs.left,
+            top: self.height + rhs.top,
+        }
+    }
+}
+
+impl std::ops::Add<ScreenSize> for ScreenPosition {
+    type Output = ScreenPosition;
+
+    fn add(self, rhs: ScreenSize) -> ScreenPosition {
+        ScreenPosition {
+            left: self.left + rhs.width,
+            top: self.top + rhs.height,
+        }
+    }
+}
+
+impl std::ops::Sub<ScreenPosition> for ScreenSize {
+    type Output = ScreenPosition;
+
+    fn sub(self, rhs: ScreenPosition) -> ScreenPosition {
+        ScreenPosition {
+            left: self.width - rhs.left,
+            top: self.height - rhs.top,
+        }
+    }
+}
+
+impl std::ops::Sub<ScreenSize> for ScreenPosition {
+    type Output = ScreenPosition;
+
+    fn sub(self, rhs: ScreenSize) -> ScreenPosition {
+        ScreenPosition {
+            left: self.left - rhs.width,
+            top: self.top - rhs.height,
+        }
+    }
+}
+
+#[derive(Debug, Clone, Copy, Default, PartialEq, Serialize, Deserialize)]
+pub struct ScreenClip {
+    pub left: f32,
+    pub right: f32,
+    pub top: f32,
+    pub bottom: f32,
+}
+
+impl From<ScreenClip> for [f32; 4] {
+    fn from(val: ScreenClip) -> Self {
+        [val.left, val.top, val.right, val.bottom]
+    }
+}
 
 #[derive(Copy, Clone, new)]
-pub struct PartialSize {
-    pub x: f32,
-    pub y: Option<f32>,
+pub struct PartialScreenSize {
+    pub width: f32,
+    pub height: Option<f32>,
+}
+
+impl PartialScreenSize {
+    pub fn finalize(self) -> ScreenSize {
+        let width = self.width;
+        let height = self.height.expect("element cannot have flexible height");
+
+        ScreenSize { width, height }
+    }
+
+    pub fn finalize_or(self, height: f32) -> ScreenSize {
+        let width = self.width;
+        let height = self.height.unwrap_or(height);
+
+        ScreenSize { width, height }
+    }
+}
+
+impl From<ScreenSize> for PartialScreenSize {
+    fn from(size: ScreenSize) -> Self {
+        Self {
+            width: size.width,
+            height: Some(size.height),
+        }
+    }
+}
+
+#[derive(Debug, Clone, Copy, Default, PartialEq, Serialize, Deserialize)]
+pub struct CornerRadius {
+    pub top_left: f32,
+    pub top_right: f32,
+    pub bottom_left: f32,
+    pub bottom_right: f32,
+}
+
+impl CornerRadius {
+    pub fn uniform(value: f32) -> Self {
+        Self {
+            top_left: value,
+            top_right: value,
+            bottom_left: value,
+            bottom_right: value,
+        }
+    }
 }
 
-impl PartialSize {
-    pub fn finalize(self) -> Vector2<f32> {
-        let x = self.x;
-        let y = self.y.expect("element cannot have flexible height");
-        Vector2::new(x, y)
+impl std::ops::Mul<f32> for CornerRadius {
+    type Output = Self;
+
+    fn mul(self, rhs: f32) -> Self {
+        Self {
+            top_left: self.top_left * rhs,
+            top_right: self.top_right * rhs,
+            bottom_left: self.bottom_left * rhs,
+            bottom_right: self.bottom_right * rhs,
+        }
     }
+}
 
-    pub fn finalize_or(self, y: f32) -> Vector2<f32> {
-        let x = self.x;
-        let y = self.y.unwrap_or(y);
-        Vector2::new(x, y)
+impl From<CornerRadius> for [f32; 4] {
+    fn from(val: CornerRadius) -> Self {
+        [val.top_left, val.top_right, val.bottom_right, val.bottom_left]
     }
 }
 
-impl From<Size> for PartialSize {
-    fn from(size: Size) -> Self {
+// TODO: Temorary, remove at some point
+impl From<cgmath::Vector4<f32>> for CornerRadius {
+    fn from(val: cgmath::Vector4<f32>) -> Self {
         Self {
-            x: size.x,
-            y: Some(size.y),
+            top_left: val.x,
+            top_right: val.y,
+            bottom_right: val.z,
+            bottom_left: val.w,
         }
     }
 }
diff --git a/src/interface/mod.rs b/src/interface/mod.rs
index b984ef16..77b90da0 100644
--- a/src/interface/mod.rs
+++ b/src/interface/mod.rs
@@ -13,7 +13,6 @@ use std::cell::RefCell;
 use std::marker::{ConstParamTy, PhantomData};
 use std::rc::Rc;
 
-use cgmath::Vector2;
 use derive_new::new;
 use option_ext::OptionExt;
 use procedural::profile;
@@ -139,7 +138,7 @@ pub struct Interface {
     windows: Vec<(Window, PostUpdate<PerWindow>)>,
     window_cache: WindowCache,
     interface_settings: InterfaceSettings,
-    available_space: Size,
+    available_space: ScreenSize,
     themes: Themes,
     dialog_handle: Option<DialogHandle>,
     mouse_cursor: MouseCursor,
@@ -152,7 +151,7 @@ impl Interface {
         game_file_loader: &mut GameFileLoader,
         sprite_loader: &mut SpriteLoader,
         action_loader: &mut ActionLoader,
-        available_space: Size,
+        available_space: ScreenSize,
     ) -> Self {
         let window_cache = WindowCache::new();
         let interface_settings = InterfaceSettings::new();
@@ -297,7 +296,7 @@ impl Interface {
 
                 // NOTE: If the window got smaller, we need to re-render the entire interface.
                 // If it got bigger, we can just draw over the previous frame.
-                match previous_size.x > new_size.x || previous_size.y > new_size.y {
+                match previous_size.width > new_size.width || previous_size.height > new_size.height {
                     true => self.post_update.render(),
                     false => post_update.render(),
                 }
@@ -327,13 +326,13 @@ impl Interface {
         (render_interface, render_window)
     }
 
-    pub fn update_window_size(&mut self, screen_size: Size) {
+    pub fn update_window_size(&mut self, screen_size: ScreenSize) {
         self.available_space = screen_size;
         self.post_update.resolve();
     }
 
     #[profile("get hovered element")]
-    pub fn hovered_element(&self, mouse_position: Position, mouse_mode: &MouseInputMode) -> (Option<ElementCell>, Option<usize>) {
+    pub fn hovered_element(&self, mouse_position: ScreenPosition, mouse_mode: &MouseInputMode) -> (Option<ElementCell>, Option<usize>) {
         for (window_index, (window, _)) in self.windows.iter().enumerate().rev() {
             match window.hovered_element(mouse_position, mouse_mode) {
                 HoverInformation::Element(hovered_element) => return (Some(hovered_element), Some(window_index)),
@@ -384,7 +383,7 @@ impl Interface {
     }
 
     #[profile]
-    pub fn drag_element(&mut self, element: &ElementCell, _window_index: usize, mouse_delta: Position) {
+    pub fn drag_element(&mut self, element: &ElementCell, _window_index: usize, mouse_delta: ScreenPosition) {
         //let (_window, post_update) = &mut self.windows[window_index];
 
         if let Some(change_event) = element.borrow_mut().drag(mouse_delta) {
@@ -418,7 +417,7 @@ impl Interface {
     }
 
     #[profile]
-    pub fn move_window(&mut self, window_index: usize, offset: Position) {
+    pub fn move_window(&mut self, window_index: usize, offset: ScreenPosition) {
         if let Some((window_class, position)) = self.windows[window_index].0.offset(self.available_space, offset) {
             self.window_cache.update_position(window_class, position);
         }
@@ -427,7 +426,7 @@ impl Interface {
     }
 
     #[profile]
-    pub fn resize_window(&mut self, window_index: usize, growth: Size) {
+    pub fn resize_window(&mut self, window_index: usize, growth: ScreenSize) {
         let (window, post_update) = &mut self.windows[window_index];
 
         let theme = match window.get_theme_kind() {
@@ -446,7 +445,7 @@ impl Interface {
 
             post_update.resolve();
 
-            if previous_size.x > new_size.x || previous_size.y > new_size.y {
+            if previous_size.width > new_size.width || previous_size.height > new_size.height {
                 self.post_update.render();
             }
         }
@@ -456,7 +455,7 @@ impl Interface {
     /// re-render a window with transparency will result in re-rendering the
     /// entire interface. This serves as a single point of truth and simplifies
     /// the rest of the code.
-    fn flag_render_windows(&mut self, start_index: usize, area: Option<(Position, Size)>) {
+    fn flag_render_windows(&mut self, start_index: usize, area: Option<(ScreenPosition, ScreenSize)>) {
         for window_index in start_index..self.windows.len() {
             let needs_render = self.windows[window_index].1.needs_render();
             let is_hovering = |(position, scale)| self.windows[window_index].0.hovers_area(position, scale);
@@ -525,16 +524,21 @@ impl Interface {
         render_target: &mut <DeferredRenderer as Renderer>::Target,
         renderer: &DeferredRenderer,
         text: &str,
-        mouse_position: Position,
+        mouse_position: ScreenPosition,
     ) {
-        let offset = Vector2::new(text.len() as f32 * -3.0, 20.0);
+        let offset = ScreenPosition {
+            left: text.len() as f32 * -3.0,
+            top: 20.0,
+        };
+
         renderer.render_text(
             render_target,
             text,
-            mouse_position + offset + Vector2::new(1.0, 1.0),
+            mouse_position + offset + ScreenPosition::uniform(1.0),
             Color::monochrome(0),
             12.0,
-        ); // move variables into theme
+        ); // TODO: move variables into theme
+
         renderer.render_text(render_target, text, mouse_position + offset, Color::monochrome(255), 12.0); // move variables into theme
     }
 
@@ -546,10 +550,15 @@ impl Interface {
         renderer: &DeferredRenderer,
         frames_per_second: usize,
     ) {
+        let text_position = ScreenPosition {
+            left: self.themes.game.overlay.text_offset.x * *self.interface_settings.scaling,
+            top: self.themes.game.overlay.text_offset.y * *self.interface_settings.scaling,
+        };
+
         renderer.render_text(
             render_target,
             &frames_per_second.to_string(),
-            *self.themes.game.overlay.text_offset * *self.interface_settings.scaling,
+            text_position,
             *self.themes.game.overlay.foreground_color,
             *self.themes.game.overlay.font_size * *self.interface_settings.scaling,
         );
@@ -560,7 +569,7 @@ impl Interface {
         &self,
         render_target: &mut <DeferredRenderer as Renderer>::Target,
         renderer: &DeferredRenderer,
-        mouse_position: Position,
+        mouse_position: ScreenPosition,
         grabbed: Option<Grabbed>,
     ) {
         if !self.mouse_cursor_hidden {
@@ -608,8 +617,8 @@ impl Interface {
     pub fn open_popup(
         &mut self,
         element: ElementCell,
-        position_tracker: Tracker<Position>,
-        size_tracker: Tracker<Size>,
+        position_tracker: Tracker<ScreenPosition>,
+        size_tracker: Tracker<ScreenSize>,
         window_index: usize,
     ) {
         let entry = &mut self.windows[window_index];
diff --git a/src/interface/theme.rs b/src/interface/theme.rs
index 351d060c..6fbff1ba 100644
--- a/src/interface/theme.rs
+++ b/src/interface/theme.rs
@@ -29,7 +29,7 @@ pub struct ButtonTheme {
     pub hovered_foreground_color: Mutable<Color, Render>,
     pub disabled_foreground_color: Mutable<Color, Render>,
     pub debug_foreground_color: Mutable<Color, Render>,
-    pub border_radius: MutableRange<Vector4<f32>, Render>,
+    pub corner_radius: MutableRange<Vector4<f32>, Render>,
     pub icon_offset: MutableRange<Vector2<f32>, Render>,
     pub icon_size: MutableRange<Vector2<f32>, Render>,
     pub icon_text_offset: MutableRange<Vector2<f32>, Render>,
@@ -48,7 +48,7 @@ impl ThemeDefault<Menu> for ButtonTheme {
             hovered_foreground_color: Mutable::new(Color::rgb(220, 170, 215)),
             disabled_foreground_color: Mutable::new(Color::monochrome(140)),
             debug_foreground_color: Mutable::new(Color::rgb(230, 140, 230)),
-            border_radius: MutableRange::new(Vector4::from_value(26.0), Vector4::from_value(0.0), Vector4::from_value(30.0)),
+            corner_radius: MutableRange::new(Vector4::from_value(26.0), Vector4::from_value(0.0), Vector4::from_value(30.0)),
             icon_offset: MutableRange::new(Vector2::new(7.0, 2.5), Vector2::zero(), Vector2::new(20.0, 20.0)),
             icon_size: MutableRange::new(Vector2::new(16.0, 16.0), Vector2::zero(), Vector2::new(20.0, 20.0)),
             icon_text_offset: MutableRange::new(Vector2::new(40.0, 4.0), Vector2::zero(), Vector2::new(100.0, 20.0)),
@@ -69,7 +69,7 @@ impl ThemeDefault<Main> for ButtonTheme {
             hovered_foreground_color: Mutable::new(Color::rgb(220, 170, 215)),
             disabled_foreground_color: Mutable::new(Color::monochrome(140)),
             debug_foreground_color: Mutable::new(Color::rgb(230, 140, 230)),
-            border_radius: MutableRange::new(Vector4::from_value(6.0), Vector4::from_value(0.0), Vector4::from_value(30.0)),
+            corner_radius: MutableRange::new(Vector4::from_value(6.0), Vector4::from_value(0.0), Vector4::from_value(30.0)),
             icon_offset: MutableRange::new(Vector2::new(7.0, 2.5), Vector2::zero(), Vector2::new(20.0, 20.0)),
             icon_size: MutableRange::new(Vector2::new(10.0, 10.0), Vector2::zero(), Vector2::new(20.0, 20.0)),
             icon_text_offset: MutableRange::new(Vector2::new(20.0, 1.0), Vector2::zero(), Vector2::new(100.0, 20.0)),
@@ -85,8 +85,8 @@ pub struct WindowTheme {
     pub background_color: Mutable<Color, Render>,
     pub title_background_color: Mutable<Color, Render>,
     pub foreground_color: Mutable<Color, Render>,
-    pub border_radius: MutableRange<Vector4<f32>, Render>,
-    pub title_border_radius: MutableRange<Vector4<f32>, Render>,
+    pub corner_radius: MutableRange<Vector4<f32>, Render>,
+    pub title_corner_radius: MutableRange<Vector4<f32>, Render>,
     pub border_size: MutableRange<Vector2<f32>, Resolve>,
     pub text_offset: MutableRange<Vector2<f32>, Render>,
     pub gaps: MutableRange<Vector2<f32>, Resolve>,
@@ -100,8 +100,8 @@ impl ThemeDefault<Menu> for WindowTheme {
             background_color: Mutable::new(Color::monochrome(30)),
             title_background_color: Mutable::new(Color::rgba(70, 60, 70, 0)),
             foreground_color: Mutable::new(Color::rgb(150, 70, 255)),
-            border_radius: MutableRange::new(Vector4::from_value(30.0), Vector4::from_value(0.0), Vector4::from_value(30.0)),
-            title_border_radius: MutableRange::new(Vector4::from_value(6.0), Vector4::from_value(0.0), Vector4::from_value(30.0)),
+            corner_radius: MutableRange::new(Vector4::from_value(30.0), Vector4::from_value(0.0), Vector4::from_value(30.0)),
+            title_corner_radius: MutableRange::new(Vector4::from_value(6.0), Vector4::from_value(0.0), Vector4::from_value(30.0)),
             border_size: MutableRange::new(Vector2::new(30.0, 30.0), Vector2::zero(), Vector2::new(30.0, 30.0)),
             text_offset: MutableRange::new(Vector2::new(5.0, -1.0), Vector2::zero(), Vector2::new(50.0, 30.0)),
             gaps: MutableRange::new(Vector2::new(9.0, 19.0), Vector2::zero(), Vector2::new(20.0, 20.0)),
@@ -117,8 +117,8 @@ impl ThemeDefault<Main> for WindowTheme {
             background_color: Mutable::new(Color::monochrome(40)),
             title_background_color: Mutable::new(Color::rgb(170, 60, 70)),
             foreground_color: Mutable::new(Color::monochrome(160)),
-            border_radius: MutableRange::new(Vector4::from_value(4.0), Vector4::from_value(0.0), Vector4::from_value(30.0)),
-            title_border_radius: MutableRange::new(Vector4::from_value(6.0), Vector4::from_value(0.0), Vector4::from_value(30.0)),
+            corner_radius: MutableRange::new(Vector4::from_value(4.0), Vector4::from_value(0.0), Vector4::from_value(30.0)),
+            title_corner_radius: MutableRange::new(Vector4::from_value(6.0), Vector4::from_value(0.0), Vector4::from_value(30.0)),
             border_size: MutableRange::new(Vector2::new(12.0, 6.0), Vector2::zero(), Vector2::new(30.0, 30.0)),
             text_offset: MutableRange::new(Vector2::new(5.0, -1.0), Vector2::zero(), Vector2::new(50.0, 30.0)),
             gaps: MutableRange::new(Vector2::new(4.0, 5.0), Vector2::zero(), Vector2::new(20.0, 20.0)),
@@ -134,7 +134,7 @@ pub struct ExpandableTheme {
     pub second_background_color: Mutable<Color, Render>,
     pub foreground_color: Mutable<Color, Render>,
     pub hovered_foreground_color: Mutable<Color, Render>,
-    pub border_radius: MutableRange<Vector4<f32>, Render>,
+    pub corner_radius: MutableRange<Vector4<f32>, Render>,
     pub border_size: MutableRange<Vector2<f32>, Resolve>,
     pub element_offset: MutableRange<Vector2<f32>, Resolve>,
     pub icon_offset: MutableRange<Vector2<f32>, Render>,
@@ -151,7 +151,7 @@ impl ThemeDefault<Menu> for ExpandableTheme {
             second_background_color: Mutable::new(Color::monochrome(45)),
             foreground_color: Mutable::new(Color::monochrome(170)),
             hovered_foreground_color: Mutable::new(Color::rgb(190, 145, 185)),
-            border_radius: MutableRange::new(Vector4::from_value(6.0), Vector4::from_value(0.0), Vector4::from_value(30.0)),
+            corner_radius: MutableRange::new(Vector4::from_value(6.0), Vector4::from_value(0.0), Vector4::from_value(30.0)),
             border_size: MutableRange::new(Vector2::new(5.0, 5.0), Vector2::zero(), Vector2::new(20.0, 20.0)),
             element_offset: MutableRange::new(Vector2::new(7.0, -2.0), Vector2::new(-10.0, -10.0), Vector2::new(30.0, 30.0)),
             icon_offset: MutableRange::new(Vector2::new(6.0, 5.0), Vector2::zero(), Vector2::new(30.0, 50.0)),
@@ -170,7 +170,7 @@ impl ThemeDefault<Main> for ExpandableTheme {
             second_background_color: Mutable::new(Color::monochrome(45)),
             foreground_color: Mutable::new(Color::monochrome(170)),
             hovered_foreground_color: Mutable::new(Color::rgb(190, 145, 185)),
-            border_radius: MutableRange::new(Vector4::from_value(6.0), Vector4::from_value(0.0), Vector4::from_value(30.0)),
+            corner_radius: MutableRange::new(Vector4::from_value(6.0), Vector4::from_value(0.0), Vector4::from_value(30.0)),
             border_size: MutableRange::new(Vector2::new(5.0, 5.0), Vector2::zero(), Vector2::new(20.0, 20.0)),
             element_offset: MutableRange::new(Vector2::new(7.0, -2.0), Vector2::new(-10.0, -10.0), Vector2::new(30.0, 30.0)),
             icon_offset: MutableRange::new(Vector2::new(6.0, 5.0), Vector2::zero(), Vector2::new(30.0, 50.0)),
@@ -186,7 +186,7 @@ impl ThemeDefault<Main> for ExpandableTheme {
 pub struct LabelTheme {
     pub background_color: Mutable<Color, Render>,
     pub foreground_color: Mutable<Color, Render>,
-    pub border_radius: MutableRange<Vector4<f32>, Render>,
+    pub corner_radius: MutableRange<Vector4<f32>, Render>,
     pub text_offset: MutableRange<Vector2<f32>, Render>,
     pub font_size: MutableRange<f32, Render>,
     pub size_constraint: SizeConstraint,
@@ -197,7 +197,7 @@ impl ThemeDefault<Menu> for LabelTheme {
         Self {
             background_color: Mutable::new(Color::monochrome(130)),
             foreground_color: Mutable::new(Color::monochrome(255)),
-            border_radius: MutableRange::new(Vector4::from_value(6.0), Vector4::from_value(0.0), Vector4::from_value(30.0)),
+            corner_radius: MutableRange::new(Vector4::from_value(6.0), Vector4::from_value(0.0), Vector4::from_value(30.0)),
             text_offset: MutableRange::new(Vector2::new(5.0, 0.0), Vector2::from_value(-10.0), Vector2::from_value(20.0)),
             font_size: MutableRange::new(14.0, 6.0, 30.0),
             size_constraint: constraint!(120 > 50% < 300, 0),
@@ -210,7 +210,7 @@ impl ThemeDefault<Main> for LabelTheme {
         Self {
             background_color: Mutable::new(Color::monochrome(130)),
             foreground_color: Mutable::new(Color::monochrome(255)),
-            border_radius: MutableRange::new(Vector4::from_value(6.0), Vector4::from_value(0.0), Vector4::from_value(30.0)),
+            corner_radius: MutableRange::new(Vector4::from_value(6.0), Vector4::from_value(0.0), Vector4::from_value(30.0)),
             text_offset: MutableRange::new(Vector2::new(5.0, 0.0), Vector2::from_value(-10.0), Vector2::from_value(20.0)),
             font_size: MutableRange::new(14.0, 6.0, 30.0),
             size_constraint: constraint!(120 > 50% < 300, 0),
@@ -223,7 +223,7 @@ pub struct ValueTheme {
     pub background_color: Mutable<Color, Render>,
     pub hovered_background_color: Mutable<Color, Render>,
     pub foreground_color: Mutable<Color, Render>,
-    pub border_radius: MutableRange<Vector4<f32>, Render>,
+    pub corner_radius: MutableRange<Vector4<f32>, Render>,
     pub text_offset: MutableRange<Vector2<f32>, Render>,
     pub font_size: MutableRange<f32, Render>,
     pub size_constraint: SizeConstraint,
@@ -235,7 +235,7 @@ impl ThemeDefault<Menu> for ValueTheme {
             background_color: Mutable::new(Color::rgb(100, 100, 100)),
             hovered_background_color: Mutable::new(Color::rgb(130, 100, 120)),
             foreground_color: Mutable::new(Color::rgb(220, 220, 220)),
-            border_radius: MutableRange::new(Vector4::from_value(6.0), Vector4::from_value(0.0), Vector4::from_value(30.0)),
+            corner_radius: MutableRange::new(Vector4::from_value(6.0), Vector4::from_value(0.0), Vector4::from_value(30.0)),
             text_offset: MutableRange::new(Vector2::new(5.0, 0.0), Vector2::from_value(-10.0), Vector2::from_value(20.0)),
             font_size: MutableRange::new(14.0, 6.0, 30.0),
             size_constraint: constraint!(60 > !, 14),
@@ -249,7 +249,7 @@ impl ThemeDefault<Main> for ValueTheme {
             background_color: Mutable::new(Color::rgb(100, 100, 100)),
             hovered_background_color: Mutable::new(Color::rgb(130, 100, 120)),
             foreground_color: Mutable::new(Color::rgb(220, 220, 220)),
-            border_radius: MutableRange::new(Vector4::from_value(6.0), Vector4::from_value(0.0), Vector4::from_value(30.0)),
+            corner_radius: MutableRange::new(Vector4::from_value(6.0), Vector4::from_value(0.0), Vector4::from_value(30.0)),
             text_offset: MutableRange::new(Vector2::new(5.0, 0.0), Vector2::from_value(-10.0), Vector2::from_value(20.0)),
             font_size: MutableRange::new(14.0, 6.0, 30.0),
             size_constraint: constraint!(60 > !, 14),
@@ -262,7 +262,7 @@ pub struct CloseButtonTheme {
     pub background_color: Mutable<Color, Render>,
     pub hovered_background_color: Mutable<Color, Render>,
     pub foreground_color: Mutable<Color, Render>,
-    pub border_radius: MutableRange<Vector4<f32>, Render>,
+    pub corner_radius: MutableRange<Vector4<f32>, Render>,
     pub text_offset: MutableRange<Vector2<f32>, Render>,
     pub font_size: MutableRange<f32, Render>,
     pub size_constraint: SizeConstraint,
@@ -274,7 +274,7 @@ impl ThemeDefault<Menu> for CloseButtonTheme {
             background_color: Mutable::new(Color::rgb(200, 100, 100)),
             hovered_background_color: Mutable::new(Color::rgb(200, 140, 100)),
             foreground_color: Mutable::new(Color::rgb(220, 220, 220)),
-            border_radius: MutableRange::new(Vector4::from_value(26.0), Vector4::from_value(0.0), Vector4::from_value(30.0)),
+            corner_radius: MutableRange::new(Vector4::from_value(26.0), Vector4::from_value(0.0), Vector4::from_value(30.0)),
             text_offset: MutableRange::new(Vector2::new(8.35, 2.55), Vector2::from_value(-10.0), Vector2::from_value(20.0)),
             font_size: MutableRange::new(20.0, 6.0, 30.0),
             size_constraint: constraint!(26, 26),
@@ -288,7 +288,7 @@ impl ThemeDefault<Main> for CloseButtonTheme {
             background_color: Mutable::new(Color::rgb(200, 100, 100)),
             hovered_background_color: Mutable::new(Color::rgb(200, 140, 100)),
             foreground_color: Mutable::new(Color::rgb(220, 220, 220)),
-            border_radius: MutableRange::new(Vector4::from_value(1.0), Vector4::from_value(0.0), Vector4::from_value(30.0)),
+            corner_radius: MutableRange::new(Vector4::from_value(1.0), Vector4::from_value(0.0), Vector4::from_value(30.0)),
             text_offset: MutableRange::new(Vector2::new(9.0, 0.0), Vector2::from_value(-10.0), Vector2::from_value(20.0)),
             font_size: MutableRange::new(12.0, 6.0, 30.0),
             size_constraint: constraint!(25, 12),
@@ -351,7 +351,7 @@ pub struct InputTheme {
     pub text_color: Mutable<Color, Render>,
     pub ghost_text_color: Mutable<Color, Render>,
     pub focused_text_color: Mutable<Color, Render>,
-    pub border_radius: MutableRange<Vector4<f32>, Render>,
+    pub corner_radius: MutableRange<Vector4<f32>, Render>,
     pub font_size: MutableRange<f32, Render>,
     pub text_offset: MutableRange<Vector2<f32>, Render>,
     pub cursor_offset: MutableRange<f32, Render>,
@@ -368,7 +368,7 @@ impl ThemeDefault<Menu> for InputTheme {
             text_color: Mutable::new(Color::monochrome(200)),
             ghost_text_color: Mutable::new(Color::monochrome(100)),
             focused_text_color: Mutable::new(Color::monochrome(200)),
-            border_radius: MutableRange::new(Vector4::from_value(26.0), Vector4::from_value(0.0), Vector4::from_value(30.0)),
+            corner_radius: MutableRange::new(Vector4::from_value(26.0), Vector4::from_value(0.0), Vector4::from_value(30.0)),
             font_size: MutableRange::new(15.0, 6.0, 50.0),
             text_offset: MutableRange::new(Vector2::new(15.0, 6.0), Vector2::from_value(0.0), Vector2::from_value(50.0)),
             cursor_offset: MutableRange::new(2.0, 0.0, 10.0),
@@ -387,7 +387,7 @@ impl ThemeDefault<Main> for InputTheme {
             text_color: Mutable::new(Color::monochrome(200)),
             ghost_text_color: Mutable::new(Color::monochrome(100)),
             focused_text_color: Mutable::new(Color::monochrome(200)),
-            border_radius: MutableRange::new(Vector4::from_value(6.0), Vector4::from_value(0.0), Vector4::from_value(30.0)),
+            corner_radius: MutableRange::new(Vector4::from_value(6.0), Vector4::from_value(0.0), Vector4::from_value(30.0)),
             font_size: MutableRange::new(14.0, 6.0, 50.0),
             text_offset: MutableRange::new(Vector2::new(4.0, 0.0), Vector2::from_value(0.0), Vector2::from_value(50.0)),
             cursor_offset: MutableRange::new(2.0, 0.0, 10.0),
@@ -437,12 +437,12 @@ impl Default for CursorTheme {
 #[derive(Serialize, Deserialize, PrototypeElement)]
 pub struct ProfilerTheme {
     pub background_color: Mutable<Color, Render>,
-    pub border_radius: MutableRange<Vector4<f32>, Render>,
+    pub corner_radius: MutableRange<Vector4<f32>, Render>,
     pub line_color: Mutable<Color, Render>,
     pub line_width: MutableRange<f32, Render>,
     pub bar_height: MutableRange<f32, Render>,
     pub bar_gap: MutableRange<Vector2<f32>, Render>,
-    pub bar_border_radius: MutableRange<Vector4<f32>, Render>,
+    pub bar_corner_radius: MutableRange<Vector4<f32>, Render>,
     pub bar_text_color: Mutable<Color, Render>,
     pub bar_text_size: MutableRange<f32, Render>,
     pub bar_text_offset: MutableRange<Vector2<f32>, Render>,
@@ -454,12 +454,12 @@ impl ThemeDefault<Menu> for ProfilerTheme {
     fn default() -> Self {
         Self {
             background_color: Mutable::new(Color::monochrome(55)),
-            border_radius: MutableRange::new(Vector4::from_value(2.0), Vector4::from_value(0.0), Vector4::from_value(30.0)),
+            corner_radius: MutableRange::new(Vector4::from_value(2.0), Vector4::from_value(0.0), Vector4::from_value(30.0)),
             line_color: Mutable::new(Color::rgb(80, 90, 80)),
             line_width: MutableRange::new(2.0, 0.5, 4.0),
             bar_height: MutableRange::new(15.0, 5.0, 30.0),
             bar_gap: MutableRange::new(Vector2::new(1.0, 5.0), Vector2::from_value(0.0), Vector2::new(10.0, 20.0)),
-            bar_border_radius: MutableRange::new(Vector4::from_value(0.0), Vector4::from_value(0.0), Vector4::from_value(15.0)),
+            bar_corner_radius: MutableRange::new(Vector4::from_value(0.0), Vector4::from_value(0.0), Vector4::from_value(15.0)),
             bar_text_color: Mutable::new(Color::monochrome(0)),
             bar_text_size: MutableRange::new(14.0, 6.0, 50.0),
             bar_text_offset: MutableRange::new(Vector2::new(7.0, 0.0), Vector2::new(0.0, -10.0), Vector2::new(40.0, 10.0)),
@@ -473,12 +473,12 @@ impl ThemeDefault<Main> for ProfilerTheme {
     fn default() -> Self {
         Self {
             background_color: Mutable::new(Color::monochrome(55)),
-            border_radius: MutableRange::new(Vector4::from_value(2.0), Vector4::from_value(0.0), Vector4::from_value(30.0)),
+            corner_radius: MutableRange::new(Vector4::from_value(2.0), Vector4::from_value(0.0), Vector4::from_value(30.0)),
             line_color: Mutable::new(Color::rgb(80, 90, 80)),
             line_width: MutableRange::new(2.0, 0.5, 4.0),
             bar_height: MutableRange::new(15.0, 5.0, 30.0),
             bar_gap: MutableRange::new(Vector2::new(1.0, 5.0), Vector2::from_value(0.0), Vector2::new(10.0, 20.0)),
-            bar_border_radius: MutableRange::new(Vector4::from_value(0.0), Vector4::from_value(0.0), Vector4::from_value(15.0)),
+            bar_corner_radius: MutableRange::new(Vector4::from_value(0.0), Vector4::from_value(0.0), Vector4::from_value(15.0)),
             bar_text_color: Mutable::new(Color::monochrome(0)),
             bar_text_size: MutableRange::new(14.0, 6.0, 50.0),
             bar_text_offset: MutableRange::new(Vector2::new(7.0, 0.0), Vector2::new(0.0, -10.0), Vector2::new(40.0, 10.0)),
diff --git a/src/interface/windows/account/login.rs b/src/interface/windows/account/login.rs
index 990b3de0..89a0a917 100644
--- a/src/interface/windows/account/login.rs
+++ b/src/interface/windows/account/login.rs
@@ -24,7 +24,7 @@ impl<'a> PrototypeWindow for LoginWindow<'a> {
         Self::WINDOW_CLASS.into()
     }
 
-    fn to_window(&self, window_cache: &WindowCache, interface_settings: &InterfaceSettings, available_space: Size) -> Window {
+    fn to_window(&self, window_cache: &WindowCache, interface_settings: &InterfaceSettings, available_space: ScreenSize) -> Window {
         let mut login_settings = LoginSettings::new();
 
         let options = self
diff --git a/src/interface/windows/account/select_server.rs b/src/interface/windows/account/select_server.rs
index 9d43f937..59578db5 100644
--- a/src/interface/windows/account/select_server.rs
+++ b/src/interface/windows/account/select_server.rs
@@ -19,7 +19,7 @@ impl PrototypeWindow for SelectServerWindow {
         Self::WINDOW_CLASS.into()
     }
 
-    fn to_window(&self, window_cache: &WindowCache, interface_settings: &InterfaceSettings, available_space: Size) -> Window {
+    fn to_window(&self, window_cache: &WindowCache, interface_settings: &InterfaceSettings, available_space: ScreenSize) -> Window {
         let elements = self
             .servers
             .iter()
diff --git a/src/interface/windows/builder.rs b/src/interface/windows/builder.rs
index 01310338..c204872d 100644
--- a/src/interface/windows/builder.rs
+++ b/src/interface/windows/builder.rs
@@ -52,7 +52,7 @@ impl WindowBuilder {
         self
     }
 
-    pub fn build(self, window_cache: &WindowCache, interface_settings: &InterfaceSettings, available_space: Size) -> Window {
+    pub fn build(self, window_cache: &WindowCache, interface_settings: &InterfaceSettings, available_space: ScreenSize) -> Window {
         let WindowBuilder {
             window_title,
             window_class,
@@ -103,7 +103,7 @@ impl WindowBuilder {
 
         let position = cached_position
             .map(|position| size_constraint.validated_position(position, size, available_space))
-            .unwrap_or((available_space - size) / 2.0);
+            .unwrap_or(ScreenPosition::from_size((available_space - size) / 2.0));
 
         Window {
             window_class,
diff --git a/src/interface/windows/cache.rs b/src/interface/windows/cache.rs
index 33b3e74f..1e724220 100644
--- a/src/interface/windows/cache.rs
+++ b/src/interface/windows/cache.rs
@@ -1,18 +1,17 @@
 use std::collections::HashMap;
 
-use cgmath::Vector2;
 use derive_new::new;
 use ron::ser::PrettyConfig;
 use serde::{Deserialize, Serialize};
 
 #[cfg(feature = "debug")]
 use crate::debug::*;
-use crate::interface::{Position, Size};
+use crate::interface::{ScreenPosition, ScreenSize};
 
 #[derive(Serialize, Deserialize, new)]
 pub struct WindowState {
-    pub position: Position,
-    pub size: Size,
+    pub position: ScreenPosition,
+    pub size: ScreenSize,
 }
 
 #[derive(Default, Serialize, Deserialize)]
@@ -52,7 +51,7 @@ impl WindowCache {
         std::fs::write("client/window_cache.ron", data).expect("unable to write file");
     }
 
-    pub fn register_window(&mut self, identifier: &str, position: Position, size: Size) {
+    pub fn register_window(&mut self, identifier: &str, position: ScreenPosition, size: ScreenSize) {
         if let Some(entry) = self.entries.get_mut(identifier) {
             entry.position = position;
             entry.size = size;
@@ -62,19 +61,19 @@ impl WindowCache {
         }
     }
 
-    pub fn update_position(&mut self, identifier: &str, position: Vector2<f32>) {
+    pub fn update_position(&mut self, identifier: &str, position: ScreenPosition) {
         if let Some(entry) = self.entries.get_mut(identifier) {
             entry.position = position;
         }
     }
 
-    pub fn update_size(&mut self, identifier: &str, size: Size) {
+    pub fn update_size(&mut self, identifier: &str, size: ScreenSize) {
         if let Some(entry) = self.entries.get_mut(identifier) {
             entry.size = size;
         }
     }
 
-    pub fn get_window_state(&self, identifier: &str) -> Option<(Position, Size)> {
+    pub fn get_window_state(&self, identifier: &str) -> Option<(ScreenPosition, ScreenSize)> {
         self.entries.get(identifier).map(|entry| (entry.position, entry.size))
     }
 }
diff --git a/src/interface/windows/character/creation.rs b/src/interface/windows/character/creation.rs
index e43ee0d0..e4c060ee 100644
--- a/src/interface/windows/character/creation.rs
+++ b/src/interface/windows/character/creation.rs
@@ -24,7 +24,7 @@ impl PrototypeWindow for CharacterCreationWindow {
         Self::WINDOW_CLASS.into()
     }
 
-    fn to_window(&self, window_cache: &WindowCache, interface_settings: &InterfaceSettings, available_space: Size) -> Window {
+    fn to_window(&self, window_cache: &WindowCache, interface_settings: &InterfaceSettings, available_space: ScreenSize) -> Window {
         let name = Rc::new(RefCell::new(String::new()));
 
         let selector = {
diff --git a/src/interface/windows/character/equipment.rs b/src/interface/windows/character/equipment.rs
index 323867ee..d31e61ea 100644
--- a/src/interface/windows/character/equipment.rs
+++ b/src/interface/windows/character/equipment.rs
@@ -17,7 +17,7 @@ impl PrototypeWindow for EquipmentWindow {
         Self::WINDOW_CLASS.into()
     }
 
-    fn to_window(&self, window_cache: &WindowCache, interface_settings: &InterfaceSettings, available_space: Size) -> Window {
+    fn to_window(&self, window_cache: &WindowCache, interface_settings: &InterfaceSettings, available_space: ScreenSize) -> Window {
         let elements = vec![EquipmentContainer::new(self.items.clone()).wrap()];
 
         WindowBuilder::default()
diff --git a/src/interface/windows/character/hotbar.rs b/src/interface/windows/character/hotbar.rs
index 35c11dd8..87ffb872 100644
--- a/src/interface/windows/character/hotbar.rs
+++ b/src/interface/windows/character/hotbar.rs
@@ -17,7 +17,7 @@ impl PrototypeWindow for HotbarWindow {
         Self::WINDOW_CLASS.into()
     }
 
-    fn to_window(&self, window_cache: &WindowCache, interface_settings: &InterfaceSettings, available_space: Size) -> Window {
+    fn to_window(&self, window_cache: &WindowCache, interface_settings: &InterfaceSettings, available_space: ScreenSize) -> Window {
         let elements = vec![HotbarContainer::new(self.skills.clone()).wrap()];
 
         WindowBuilder::default()
diff --git a/src/interface/windows/character/inventory.rs b/src/interface/windows/character/inventory.rs
index 826950fc..ce4db2ea 100644
--- a/src/interface/windows/character/inventory.rs
+++ b/src/interface/windows/character/inventory.rs
@@ -17,7 +17,7 @@ impl PrototypeWindow for InventoryWindow {
         Self::WINDOW_CLASS.into()
     }
 
-    fn to_window(&self, window_cache: &WindowCache, interface_settings: &InterfaceSettings, available_space: Size) -> Window {
+    fn to_window(&self, window_cache: &WindowCache, interface_settings: &InterfaceSettings, available_space: ScreenSize) -> Window {
         let elements = vec![InventoryContainer::new(self.items.clone()).wrap()];
 
         WindowBuilder::default()
diff --git a/src/interface/windows/character/overview.rs b/src/interface/windows/character/overview.rs
index b340caec..5a698e36 100644
--- a/src/interface/windows/character/overview.rs
+++ b/src/interface/windows/character/overview.rs
@@ -16,7 +16,7 @@ impl PrototypeWindow for CharacterOverviewWindow {
         Self::WINDOW_CLASS.into()
     }
 
-    fn to_window(&self, window_cache: &WindowCache, interface_settings: &InterfaceSettings, available_space: Size) -> Window {
+    fn to_window(&self, window_cache: &WindowCache, interface_settings: &InterfaceSettings, available_space: ScreenSize) -> Window {
         let elements = vec![
             /*Text::default()
                 .with_text(|| format!("base level: {}", player.get_base_level()))
diff --git a/src/interface/windows/character/selection.rs b/src/interface/windows/character/selection.rs
index a29da365..584229b7 100644
--- a/src/interface/windows/character/selection.rs
+++ b/src/interface/windows/character/selection.rs
@@ -20,7 +20,7 @@ impl PrototypeWindow for CharacterSelectionWindow {
         Self::WINDOW_CLASS.into()
     }
 
-    fn to_window(&self, window_cache: &WindowCache, interface_settings: &InterfaceSettings, available_space: Size) -> Window {
+    fn to_window(&self, window_cache: &WindowCache, interface_settings: &InterfaceSettings, available_space: ScreenSize) -> Window {
         let elements = (0..self.slot_count)
             .map(|slot| CharacterPreview::new(self.characters.clone(), self.move_request.clone(), slot).wrap())
             .collect();
diff --git a/src/interface/windows/character/skill_tree.rs b/src/interface/windows/character/skill_tree.rs
index c3c64e82..0f6ab7ad 100644
--- a/src/interface/windows/character/skill_tree.rs
+++ b/src/interface/windows/character/skill_tree.rs
@@ -17,7 +17,7 @@ impl PrototypeWindow for SkillTreeWindow {
         Self::WINDOW_CLASS.into()
     }
 
-    fn to_window(&self, window_cache: &WindowCache, interface_settings: &InterfaceSettings, available_space: Size) -> Window {
+    fn to_window(&self, window_cache: &WindowCache, interface_settings: &InterfaceSettings, available_space: ScreenSize) -> Window {
         let elements = vec![SkillTreeContainer::new(self.skills.clone()).wrap()];
 
         WindowBuilder::default()
diff --git a/src/interface/windows/debug/commands.rs b/src/interface/windows/debug/commands.rs
index 4b398b41..aec19cee 100644
--- a/src/interface/windows/debug/commands.rs
+++ b/src/interface/windows/debug/commands.rs
@@ -17,7 +17,7 @@ impl PrototypeWindow for CommandsWindow {
         Self::WINDOW_CLASS.into()
     }
 
-    fn to_window(&self, window_cache: &WindowCache, interface_settings: &InterfaceSettings, available_space: Size) -> Window {
+    fn to_window(&self, window_cache: &WindowCache, interface_settings: &InterfaceSettings, available_space: ScreenSize) -> Window {
         let input_text = Rc::new(RefCell::new(String::new()));
 
         let class_action = {
diff --git a/src/interface/windows/debug/inspector.rs b/src/interface/windows/debug/inspector.rs
index f3ffbcd4..c5ac99e3 100644
--- a/src/interface/windows/debug/inspector.rs
+++ b/src/interface/windows/debug/inspector.rs
@@ -14,7 +14,7 @@ impl FrameInspectorWindow {
 }
 
 impl PrototypeWindow for FrameInspectorWindow {
-    fn to_window(&self, window_cache: &WindowCache, interface_settings: &InterfaceSettings, available_space: Size) -> Window {
+    fn to_window(&self, window_cache: &WindowCache, interface_settings: &InterfaceSettings, available_space: ScreenSize) -> Window {
         let elements = vec![FrameInspectorView::new(self.measurement.clone()).wrap()];
 
         WindowBuilder::default()
diff --git a/src/interface/windows/debug/maps.rs b/src/interface/windows/debug/maps.rs
index d40336c7..e1f2294b 100644
--- a/src/interface/windows/debug/maps.rs
+++ b/src/interface/windows/debug/maps.rs
@@ -16,7 +16,7 @@ impl PrototypeWindow for MapsWindow {
         Self::WINDOW_CLASS.into()
     }
 
-    fn to_window(&self, window_cache: &WindowCache, interface_settings: &InterfaceSettings, available_space: Size) -> Window {
+    fn to_window(&self, window_cache: &WindowCache, interface_settings: &InterfaceSettings, available_space: ScreenSize) -> Window {
         let map_warps = [
             ("geffen", Vector2::new(119, 59)),
             ("alberta", Vector2::new(28, 234)),
diff --git a/src/interface/windows/debug/packet.rs b/src/interface/windows/debug/packet.rs
index 94a89c8d..7d7e73d1 100644
--- a/src/interface/windows/debug/packet.rs
+++ b/src/interface/windows/debug/packet.rs
@@ -29,7 +29,7 @@ impl<const N: usize> PrototypeWindow for PacketWindow<N> {
         Self::WINDOW_CLASS.into()
     }
 
-    fn to_window(&self, window_cache: &WindowCache, interface_settings: &InterfaceSettings, available_space: Size) -> Window {
+    fn to_window(&self, window_cache: &WindowCache, interface_settings: &InterfaceSettings, available_space: ScreenSize) -> Window {
         let elements = vec![PacketView::new(self.packets.clone(), self.show_pings.new_remote()).wrap()];
 
         let clear_selector = {
diff --git a/src/interface/windows/debug/profiler.rs b/src/interface/windows/debug/profiler.rs
index da5a2637..6d831848 100644
--- a/src/interface/windows/debug/profiler.rs
+++ b/src/interface/windows/debug/profiler.rs
@@ -23,7 +23,7 @@ impl PrototypeWindow for ProfilerWindow {
         Self::WINDOW_CLASS.into()
     }
 
-    fn to_window(&self, window_cache: &WindowCache, interface_settings: &InterfaceSettings, available_space: Size) -> Window {
+    fn to_window(&self, window_cache: &WindowCache, interface_settings: &InterfaceSettings, available_space: ScreenSize) -> Window {
         let toggle_halting = || {
             let is_profiler_halted = is_profiler_halted();
             set_profiler_halted(!is_profiler_halted);
diff --git a/src/interface/windows/debug/time.rs b/src/interface/windows/debug/time.rs
index 33df7571..62d4a10d 100644
--- a/src/interface/windows/debug/time.rs
+++ b/src/interface/windows/debug/time.rs
@@ -15,7 +15,7 @@ impl PrototypeWindow for TimeWindow {
         Self::WINDOW_CLASS.into()
     }
 
-    fn to_window(&self, window_cache: &WindowCache, interface_settings: &InterfaceSettings, available_space: Size) -> Window {
+    fn to_window(&self, window_cache: &WindowCache, interface_settings: &InterfaceSettings, available_space: ScreenSize) -> Window {
         // TODO: Unify Set* events into one that takes a specific time
         let elements = vec![
             Button::default().with_text("Set dawn").with_event(UserEvent::SetDawn).wrap(),
diff --git a/src/interface/windows/friends/list.rs b/src/interface/windows/friends/list.rs
index 4c1b7516..44b7b361 100644
--- a/src/interface/windows/friends/list.rs
+++ b/src/interface/windows/friends/list.rs
@@ -20,7 +20,7 @@ impl PrototypeWindow for FriendsWindow {
         Self::WINDOW_CLASS.into()
     }
 
-    fn to_window(&self, window_cache: &WindowCache, interface_settings: &InterfaceSettings, available_space: Size) -> Window {
+    fn to_window(&self, window_cache: &WindowCache, interface_settings: &InterfaceSettings, available_space: ScreenSize) -> Window {
         let friend_name = Rc::new(RefCell::new(String::new()));
 
         let add_action = {
diff --git a/src/interface/windows/friends/request.rs b/src/interface/windows/friends/request.rs
index 7f9b3fd4..abe01c27 100644
--- a/src/interface/windows/friends/request.rs
+++ b/src/interface/windows/friends/request.rs
@@ -15,7 +15,7 @@ impl FriendRequestWindow {
 }
 
 impl PrototypeWindow for FriendRequestWindow {
-    fn to_window(&self, window_cache: &WindowCache, interface_settings: &InterfaceSettings, available_space: Size) -> Window {
+    fn to_window(&self, window_cache: &WindowCache, interface_settings: &InterfaceSettings, available_space: ScreenSize) -> Window {
         let elements = vec![
             Text::default()
                 .with_text(format!("^ffaa00{}^000000 wants to be friends with you", self.friend.name))
diff --git a/src/interface/windows/generic/chat.rs b/src/interface/windows/generic/chat.rs
index 3afd4eda..ed3ca1f5 100644
--- a/src/interface/windows/generic/chat.rs
+++ b/src/interface/windows/generic/chat.rs
@@ -24,7 +24,7 @@ impl PrototypeWindow for ChatWindow {
         ChatWindow::WINDOW_CLASS.into()
     }
 
-    fn to_window(&self, window_cache: &WindowCache, interface_settings: &InterfaceSettings, available_space: Size) -> Window {
+    fn to_window(&self, window_cache: &WindowCache, interface_settings: &InterfaceSettings, available_space: ScreenSize) -> Window {
         let input_text = Rc::new(RefCell::new(String::new()));
 
         let button_selector = {
diff --git a/src/interface/windows/generic/dialog.rs b/src/interface/windows/generic/dialog.rs
index 69a35c40..13486e39 100644
--- a/src/interface/windows/generic/dialog.rs
+++ b/src/interface/windows/generic/dialog.rs
@@ -27,7 +27,7 @@ impl PrototypeWindow for DialogWindow {
         Self::WINDOW_CLASS.into()
     }
 
-    fn to_window(&self, window_cache: &WindowCache, interface_settings: &InterfaceSettings, available_space: Size) -> Window {
+    fn to_window(&self, window_cache: &WindowCache, interface_settings: &InterfaceSettings, available_space: ScreenSize) -> Window {
         let elements = vec![DialogContainer::new(self.elements.new_remote(), self.npc_id).wrap()];
 
         WindowBuilder::default()
diff --git a/src/interface/windows/generic/error.rs b/src/interface/windows/generic/error.rs
index 715183ba..59f7720b 100644
--- a/src/interface/windows/generic/error.rs
+++ b/src/interface/windows/generic/error.rs
@@ -10,7 +10,7 @@ pub struct ErrorWindow {
 }
 
 impl PrototypeWindow for ErrorWindow {
-    fn to_window(&self, window_cache: &WindowCache, interface_settings: &InterfaceSettings, available_space: Size) -> Window {
+    fn to_window(&self, window_cache: &WindowCache, interface_settings: &InterfaceSettings, available_space: ScreenSize) -> Window {
         let elements = vec![
             Text::default()
                 .with_text(self.message.clone())
diff --git a/src/interface/windows/generic/menu.rs b/src/interface/windows/generic/menu.rs
index c1811c3a..f7c2e194 100644
--- a/src/interface/windows/generic/menu.rs
+++ b/src/interface/windows/generic/menu.rs
@@ -15,7 +15,7 @@ impl PrototypeWindow for MenuWindow {
         Self::WINDOW_CLASS.into()
     }
 
-    fn to_window(&self, window_cache: &WindowCache, interface_settings: &InterfaceSettings, available_space: Size) -> Window {
+    fn to_window(&self, window_cache: &WindowCache, interface_settings: &InterfaceSettings, available_space: ScreenSize) -> Window {
         let elements = vec![
             Button::default()
                 .with_text("Graphics settings")
diff --git a/src/interface/windows/mod.rs b/src/interface/windows/mod.rs
index 354684bb..fb5372e0 100644
--- a/src/interface/windows/mod.rs
+++ b/src/interface/windows/mod.rs
@@ -10,8 +10,6 @@ mod mutable;
 mod prototype;
 mod settings;
 
-use cgmath::{Vector2, Vector4};
-
 pub use self::account::*;
 pub use self::builder::WindowBuilder;
 pub use self::cache::*;
@@ -30,11 +28,11 @@ use crate::loaders::FontLoader;
 
 pub struct Window {
     window_class: Option<String>,
-    position: Vector2<f32>,
+    position: ScreenPosition,
     size_constraint: SizeConstraint,
-    size: Vector2<f32>,
+    size: ScreenSize,
     elements: Vec<ElementCell>,
-    popup_element: Option<(ElementCell, Tracker<Position>, Tracker<Size>)>,
+    popup_element: Option<(ElementCell, Tracker<ScreenPosition>, Tracker<ScreenSize>)>,
     closable: bool,
     background_color: Option<ColorSelector>,
     theme_kind: ThemeKind,
@@ -69,18 +67,27 @@ impl Window {
         font_loader: Rc<RefCell<FontLoader>>,
         interface_settings: &InterfaceSettings,
         theme: &InterfaceTheme,
-        available_space: Size,
-    ) -> (Option<&str>, Vector2<f32>, Size) {
+        available_space: ScreenSize,
+    ) -> (Option<&str>, ScreenPosition, ScreenSize) {
         let height = match self.size_constraint.height.is_flexible() {
             true => None,
-            false => Some(self.size.y),
+            false => Some(self.size.height),
+        };
+
+        let border_size = ScreenSize {
+            width: theme.window.border_size.x,
+            height: theme.window.border_size.y,
+        };
+        let gaps = ScreenSize {
+            width: theme.window.gaps.x,
+            height: theme.window.gaps.y,
         };
 
         let mut placement_resolver = PlacementResolver::new(
             font_loader.clone(),
-            PartialSize::new(self.size.x, height),
-            *theme.window.border_size,
-            *theme.window.gaps,
+            PartialScreenSize::new(self.size.width, height),
+            border_size,
+            gaps,
             *interface_settings.scaling,
         );
 
@@ -92,11 +99,11 @@ impl Window {
             let final_height = theme.window.border_size.y + placement_resolver.final_height();
             let final_height = self.size_constraint.validated_height(
                 final_height,
-                available_space.y.into(),
-                available_space.y.into(),
+                available_space.height.into(),
+                available_space.height.into(),
                 *interface_settings.scaling,
             );
-            self.size.y = final_height;
+            self.size.height = final_height;
             self.validate_size(interface_settings, available_space);
         }
 
@@ -107,9 +114,9 @@ impl Window {
 
             let mut placement_resolver = PlacementResolver::new(
                 font_loader,
-                PartialSize::new(size.x, Some(200.0)),
-                Vector2::new(0.0, 0.0), //*theme.window.border_size, // TODO: Popup
-                Vector2::new(0.0, 0.0), //*theme.window.gaps, // TODO: Popup
+                PartialScreenSize::new(size.width, Some(200.0)),
+                ScreenSize::default(), //*theme.window.border_size, // TODO: Popup
+                ScreenSize::default(), //*theme.window.gaps, // TODO: Popup
                 *interface_settings.scaling,
             );
 
@@ -137,23 +144,24 @@ impl Window {
         self.elements[0].borrow().restore_focus(self.elements[0].clone())
     }
 
-    pub fn hovered_element(&self, mouse_position: Vector2<f32>, mouse_mode: &MouseInputMode) -> HoverInformation {
-        let absolute_position = mouse_position - self.position;
+    pub fn hovered_element(&self, mouse_position: ScreenPosition, mouse_mode: &MouseInputMode) -> HoverInformation {
+        let absolute_position = ScreenPosition::from_size(mouse_position - self.position);
 
         if let Some((popup, position_tracker, _)) = &self.popup_element {
             let position = position_tracker().unwrap(); // FIX: Don't unwrap obviously
+            let position = ScreenPosition::from_size(mouse_position - position);
 
-            match popup.borrow().hovered_element(mouse_position - position, mouse_mode) {
+            match popup.borrow().hovered_element(position, mouse_mode) {
                 HoverInformation::Hovered => return HoverInformation::Element(popup.clone()),
                 HoverInformation::Missed => {}
                 hover_information => return hover_information,
             }
         }
 
-        if absolute_position.x >= 0.0
-            && absolute_position.y >= 0.0
-            && absolute_position.x <= self.size.x
-            && absolute_position.y <= self.size.y
+        if absolute_position.left >= 0.0
+            && absolute_position.top >= 0.0
+            && absolute_position.left <= self.size.width
+            && absolute_position.top <= self.size.height
         {
             for element in &self.elements {
                 match element.borrow().hovered_element(absolute_position, mouse_mode) {
@@ -169,21 +177,21 @@ impl Window {
         HoverInformation::Missed
     }
 
-    pub fn get_area(&self) -> (Position, Size) {
+    pub fn get_area(&self) -> (ScreenPosition, ScreenSize) {
         (self.position, self.size)
     }
 
-    pub fn hovers_area(&self, position: Position, size: Size) -> bool {
+    pub fn hovers_area(&self, position: ScreenPosition, size: ScreenSize) -> bool {
         let self_combined = self.position + self.size;
         let area_combined = position + size;
 
-        self_combined.x > position.x
-            && self.position.x < area_combined.x
-            && self_combined.y > position.y
-            && self.position.y < area_combined.y
+        self_combined.left > position.left
+            && self.position.left < area_combined.left
+            && self_combined.top > position.top
+            && self.position.top < area_combined.top
     }
 
-    pub fn offset(&mut self, available_space: Size, offset: Position) -> Option<(&str, Position)> {
+    pub fn offset(&mut self, available_space: ScreenSize, offset: ScreenPosition) -> Option<(&str, ScreenPosition)> {
         self.position += offset;
         self.validate_position(available_space);
         self.window_class
@@ -191,7 +199,7 @@ impl Window {
             .map(|window_class| (window_class.as_str(), self.position))
     }
 
-    fn validate_position(&mut self, available_space: Size) {
+    fn validate_position(&mut self, available_space: ScreenSize) {
         self.position = self.size_constraint.validated_position(self.position, self.size, available_space);
     }
 
@@ -199,21 +207,21 @@ impl Window {
         &mut self,
         interface_settings: &InterfaceSettings,
         _theme: &InterfaceTheme,
-        available_space: Size,
-        growth: Size,
-    ) -> (Option<&str>, Size) {
+        available_space: ScreenSize,
+        growth: ScreenSize,
+    ) -> (Option<&str>, ScreenSize) {
         self.size += growth;
         self.validate_size(interface_settings, available_space);
         (self.window_class.as_deref(), self.size)
     }
 
-    fn validate_size(&mut self, interface_settings: &InterfaceSettings, available_space: Size) {
+    fn validate_size(&mut self, interface_settings: &InterfaceSettings, available_space: ScreenSize) {
         self.size = self
             .size_constraint
             .validated_size(self.size, available_space, *interface_settings.scaling);
     }
 
-    pub fn open_popup(&mut self, element: ElementCell, position_tracker: Tracker<Position>, size_tracker: Tracker<Size>) {
+    pub fn open_popup(&mut self, element: ElementCell, position_tracker: Tracker<ScreenPosition>, size_tracker: Tracker<ScreenSize>) {
         // NOTE: Very important to link back
         let weak_element = Rc::downgrade(&element);
         element.borrow_mut().link_back(weak_element, None);
@@ -236,19 +244,19 @@ impl Window {
         focused_element: Option<&dyn Element>,
         mouse_mode: &MouseInputMode,
     ) {
-        let clip_size = Vector4::new(
-            self.position.x,
-            self.position.y,
-            self.position.x + self.size.x,
-            self.position.y + self.size.y,
-        );
+        let screen_clip = ScreenClip {
+            left: self.position.left,
+            top: self.position.top,
+            right: self.position.left + self.size.width,
+            bottom: self.position.top + self.size.height,
+        };
 
         renderer.render_rectangle(
             render_target,
             self.position,
             self.size,
-            clip_size,
-            *theme.window.border_radius,
+            screen_clip,
+            (*theme.window.corner_radius).into(),
             self.get_background_color(theme),
         );
 
@@ -260,7 +268,7 @@ impl Window {
                 interface_settings,
                 theme,
                 self.position,
-                clip_size,
+                screen_clip,
                 hovered_element,
                 focused_element,
                 mouse_mode,
@@ -278,7 +286,7 @@ impl Window {
                 interface_settings,
                 theme,
                 position,
-                clip_size,
+                screen_clip,
                 hovered_element,
                 focused_element,
                 mouse_mode,
diff --git a/src/interface/windows/mutable/color.rs b/src/interface/windows/mutable/color.rs
index 4cd2ffcc..5a036095 100644
--- a/src/interface/windows/mutable/color.rs
+++ b/src/interface/windows/mutable/color.rs
@@ -12,7 +12,7 @@ pub struct ColorWindow {
 }
 
 impl PrototypeWindow for ColorWindow {
-    fn to_window(&self, window_cache: &WindowCache, interface_settings: &InterfaceSettings, available_space: Size) -> Window {
+    fn to_window(&self, window_cache: &WindowCache, interface_settings: &InterfaceSettings, available_space: ScreenSize) -> Window {
         let rgb_elements = vec![
             Headline::new("red".to_string(), Headline::DEFAULT_SIZE).wrap(),
             Slider::new(unsafe { &(*self.color_pointer).red as *const u8 }, 0, 255, self.change_event).wrap(),
diff --git a/src/interface/windows/mutable/number.rs b/src/interface/windows/mutable/number.rs
index 575eddd3..c0562dda 100644
--- a/src/interface/windows/mutable/number.rs
+++ b/src/interface/windows/mutable/number.rs
@@ -17,7 +17,7 @@ pub struct NumberWindow<T> {
 }
 
 impl<T: Zero + NumOps + NumCast + Copy + PartialOrd + 'static> PrototypeWindow for NumberWindow<T> {
-    fn to_window(&self, window_cache: &WindowCache, interface_settings: &InterfaceSettings, available_space: Size) -> Window {
+    fn to_window(&self, window_cache: &WindowCache, interface_settings: &InterfaceSettings, available_space: ScreenSize) -> Window {
         let elements = vec![
             Headline::new("value".to_string(), Headline::DEFAULT_SIZE).wrap(),
             Slider::new(
diff --git a/src/interface/windows/mutable/vector.rs b/src/interface/windows/mutable/vector.rs
index efa8e4bc..be9c6e49 100644
--- a/src/interface/windows/mutable/vector.rs
+++ b/src/interface/windows/mutable/vector.rs
@@ -27,7 +27,7 @@ where
     T: Array,
     T::Element: Zero + NumOps + NumCast + Copy + PartialOrd + Display + 'static,
 {
-    fn to_window(&self, window_cache: &WindowCache, interface_settings: &InterfaceSettings, available_space: Size) -> Window {
+    fn to_window(&self, window_cache: &WindowCache, interface_settings: &InterfaceSettings, available_space: ScreenSize) -> Window {
         const LABELS: [char; 4] = ['x', 'y', 'z', 'w'];
 
         let mut elements = Vec::new();
diff --git a/src/interface/windows/prototype.rs b/src/interface/windows/prototype.rs
index dca1a4d6..bdee874c 100644
--- a/src/interface/windows/prototype.rs
+++ b/src/interface/windows/prototype.rs
@@ -1,9 +1,9 @@
-use crate::interface::{InterfaceSettings, Size, Window, WindowCache};
+use crate::interface::{InterfaceSettings, ScreenSize, Window, WindowCache};
 
 pub trait PrototypeWindow {
     fn window_class(&self) -> Option<&str> {
         None
     }
 
-    fn to_window(&self, window_cache: &WindowCache, interface_settings: &InterfaceSettings, available_space: Size) -> Window;
+    fn to_window(&self, window_cache: &WindowCache, interface_settings: &InterfaceSettings, available_space: ScreenSize) -> Window;
 }
diff --git a/src/interface/windows/settings/audio.rs b/src/interface/windows/settings/audio.rs
index 1f72b95f..593fc77d 100644
--- a/src/interface/windows/settings/audio.rs
+++ b/src/interface/windows/settings/audio.rs
@@ -1,6 +1,6 @@
 use procedural::*;
 
-use crate::interface::{InterfaceSettings, PrototypeWindow, Size, Window, WindowBuilder, WindowCache};
+use crate::interface::{InterfaceSettings, PrototypeWindow, ScreenSize, Window, WindowBuilder, WindowCache};
 
 #[derive(Default)]
 pub struct AudioSettingsWindow {}
@@ -14,7 +14,7 @@ impl PrototypeWindow for AudioSettingsWindow {
         Self::WINDOW_CLASS.into()
     }
 
-    fn to_window(&self, window_cache: &WindowCache, interface_settings: &InterfaceSettings, available_space: Size) -> Window {
+    fn to_window(&self, window_cache: &WindowCache, interface_settings: &InterfaceSettings, available_space: ScreenSize) -> Window {
         let elements = vec![];
 
         WindowBuilder::default()
diff --git a/src/interface/windows/settings/graphics.rs b/src/interface/windows/settings/graphics.rs
index 8220d76c..0564bf79 100644
--- a/src/interface/windows/settings/graphics.rs
+++ b/src/interface/windows/settings/graphics.rs
@@ -19,7 +19,7 @@ impl PrototypeWindow for GraphicsSettingsWindow {
         Self::WINDOW_CLASS.into()
     }
 
-    fn to_window(&self, window_cache: &WindowCache, interface_settings: &InterfaceSettings, available_space: Size) -> Window {
+    fn to_window(&self, window_cache: &WindowCache, interface_settings: &InterfaceSettings, available_space: ScreenSize) -> Window {
         let mut elements = vec![
             Text::default().with_text("Shadow detail").with_width(dimension!(50%)).wrap(),
             PickList::default()
diff --git a/src/interface/windows/settings/render.rs b/src/interface/windows/settings/render.rs
index f0e4ed7e..07d78f74 100644
--- a/src/interface/windows/settings/render.rs
+++ b/src/interface/windows/settings/render.rs
@@ -108,7 +108,7 @@ impl PrototypeWindow for RenderSettingsWindow {
         Self::WINDOW_CLASS.into()
     }
 
-    fn to_window(&self, window_cache: &WindowCache, interface_settings: &InterfaceSettings, available_space: Size) -> Window {
+    fn to_window(&self, window_cache: &WindowCache, interface_settings: &InterfaceSettings, available_space: ScreenSize) -> Window {
         let elements = vec![
             general_expandable(),
             map_expandable(),
diff --git a/src/loaders/action/mod.rs b/src/loaders/action/mod.rs
index 0012f436..c7a70d50 100644
--- a/src/loaders/action/mod.rs
+++ b/src/loaders/action/mod.rs
@@ -2,7 +2,7 @@ use std::collections::HashMap;
 use std::ops::Mul;
 use std::sync::Arc;
 
-use cgmath::{Array, Vector2, Vector4};
+use cgmath::{Array, Vector2};
 use derive_new::new;
 use procedural::*;
 use vulkano::image::view::ImageView;
@@ -11,7 +11,7 @@ use super::Sprite;
 #[cfg(feature = "debug")]
 use crate::debug::*;
 use crate::graphics::{Color, Renderer, SpriteRenderer};
-use crate::interface::InterfaceSettings;
+use crate::interface::{InterfaceSettings, ScreenClip, ScreenPosition, ScreenSize};
 use crate::loaders::{ByteStream, FromBytes, GameFileLoader, MinorFirst, Version, FALLBACK_ACTIONS_FILE};
 use crate::network::ClientTick;
 
@@ -116,7 +116,7 @@ impl Actions {
         renderer: &T,
         sprite: &Sprite,
         animation_state: &AnimationState,
-        position: Vector2<f32>,
+        position: ScreenPosition,
         camera_direction: usize,
         color: Color,
         interface_settings: &InterfaceSettings,
@@ -160,14 +160,31 @@ impl Actions {
             let zoom2 = sprite_clip.zoom2.unwrap_or_else(|| Vector2::from_value(1.0));
 
             let final_size = dimesions.zip(zoom2, f32::mul) * zoom;
-            let final_position = position + offset - final_size / 2.0;
+            let final_position = Vector2::new(position.left, position.top) + offset - final_size / 2.0;
+
+            let final_size = ScreenSize {
+                width: final_size.x,
+                height: final_size.y,
+            };
+
+            let final_position = ScreenPosition {
+                left: final_position.x,
+                top: final_position.y,
+            };
+
+            let screen_clip = ScreenClip {
+                left: 0.0,
+                top: 0.0,
+                right: f32::MAX,
+                bottom: f32::MAX,
+            };
 
             renderer.render_sprite(
                 render_target,
                 texture.clone(),
                 final_position,
                 final_size,
-                Vector4::new(0.0, 0.0, f32::MAX, f32::MAX),
+                screen_clip,
                 color,
                 false,
             );
diff --git a/src/main.rs b/src/main.rs
index ff1da626..f830096d 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -315,7 +315,7 @@ fn main() {
         &mut game_file_loader,
         &mut sprite_loader,
         &mut action_loader,
-        swapchain_holder.window_size_f32(),
+        swapchain_holder.window_screen_size(),
     );
     let mut focus_state = FocusState::default();
 
@@ -384,7 +384,10 @@ fn main() {
                     .downcast_ref::<winit::window::Window>()
                     .unwrap()
                     .inner_size();
-                interface.update_window_size(Size::new(window_size.width as f32, window_size.height as f32));
+                interface.update_window_size(ScreenSize {
+                    width: window_size.width as f32,
+                    height: window_size.height as f32,
+                });
                 swapchain_holder.update_window_size(window_size.into());
             }
             Event::WindowEvent {
@@ -1240,7 +1243,7 @@ fn main() {
                 let image_number = swapchain_holder.get_image_number();
                 let directional_shadow_image = directional_shadow_targets[image_number].image.clone();
                 let screen_target = &mut screen_targets[image_number];
-                let window_size = swapchain_holder.window_size_f32();
+                let window_size = swapchain_holder.window_screen_size();
                 let window_size_u32 = swapchain_holder.window_size_u32();
                 let entities = &entities[..];
                 #[cfg(feature = "debug")]
diff --git a/src/world/entity/mod.rs b/src/world/entity/mod.rs
index 2bfd4ad9..6872d1b2 100644
--- a/src/world/entity/mod.rs
+++ b/src/world/entity/mod.rs
@@ -8,7 +8,7 @@ use vulkano::buffer::Subbuffer;
 #[cfg(feature = "debug")]
 use crate::graphics::MarkerRenderer;
 use crate::graphics::{Camera, DeferredRenderer, EntityRenderer, ModelVertex, Renderer};
-use crate::interface::{GameTheme, InterfaceSettings, PrototypeWindow, Size, Window, WindowCache};
+use crate::interface::{GameTheme, InterfaceSettings, PrototypeWindow, ScreenPosition, ScreenSize, Window, WindowCache};
 use crate::loaders::{ActionLoader, Actions, AnimationState, GameFileLoader, ScriptLoader, Sprite, SpriteLoader};
 use crate::network::{AccountId, CharacterInformation, ClientTick, EntityData, EntityId, Sex, StatusType};
 use crate::world::Map;
@@ -821,7 +821,7 @@ impl Player {
         renderer: &DeferredRenderer,
         camera: &dyn Camera,
         theme: &GameTheme,
-        window_size: Vector2<f32>,
+        window_size: ScreenSize,
     ) {
         let (view_matrix, projection_matrix) = camera.view_projection_matrices();
         let clip_space_position = (projection_matrix * view_matrix) * self.common.position.extend(1.0);
@@ -830,7 +830,10 @@ impl Player {
             clip_space_position.y / clip_space_position.w + 1.0,
         );
         let screen_position = screen_position / 2.0;
-        let final_position = Vector2::new(screen_position.x * window_size.x, screen_position.y * window_size.y + 5.0);
+        let final_position = ScreenPosition {
+            left: screen_position.x * window_size.width,
+            top: screen_position.y * window_size.height + 5.0,
+        };
 
         let bar_width = *theme.status_bar.player_bar_width;
         let gap = *theme.status_bar.gap;
@@ -839,17 +842,35 @@ impl Player {
 
         let mut offset = 0.0;
 
+        let background_position = final_position
+            - ScreenSize {
+                width: theme.status_bar.border_size.x,
+                height: theme.status_bar.border_size.y,
+            }
+            - ScreenSize::only_width(bar_width / 2.0);
+
+        let background_size = ScreenSize {
+            width: bar_width,
+            height: total_height,
+        } + ScreenSize {
+            width: theme.status_bar.border_size.x,
+            height: theme.status_bar.border_size.y,
+        } * 2.0;
+
         renderer.render_rectangle(
             render_target,
-            final_position - *theme.status_bar.border_size - Vector2::new(bar_width / 2.0, 0.0),
-            Vector2::new(bar_width, total_height) + *theme.status_bar.border_size * 2.0,
+            background_position,
+            background_size,
             *theme.status_bar.background_color,
         );
 
         renderer.render_bar(
             render_target,
             final_position,
-            Vector2::new(bar_width, *theme.status_bar.health_height),
+            ScreenSize {
+                width: bar_width,
+                height: *theme.status_bar.health_height,
+            },
             *theme.status_bar.player_health_color,
             self.common.maximum_health_points as f32,
             self.common.health_points as f32,
@@ -859,8 +880,11 @@ impl Player {
 
         renderer.render_bar(
             render_target,
-            final_position + Vector2::new(0.0, offset),
-            Vector2::new(bar_width, *theme.status_bar.spell_point_height),
+            final_position + ScreenPosition::only_top(offset),
+            ScreenSize {
+                width: bar_width,
+                height: *theme.status_bar.spell_point_height,
+            },
             *theme.status_bar.spell_point_color,
             self.maximum_spell_points as f32,
             self.spell_points as f32,
@@ -870,8 +894,11 @@ impl Player {
 
         renderer.render_bar(
             render_target,
-            final_position + Vector2::new(0.0, offset),
-            Vector2::new(bar_width, *theme.status_bar.activity_point_height),
+            final_position + ScreenPosition::only_top(offset),
+            ScreenSize {
+                width: bar_width,
+                height: *theme.status_bar.activity_point_height,
+            },
             *theme.status_bar.activity_point_color,
             self.maximum_activity_points as f32,
             self.activity_points as f32,
@@ -921,7 +948,7 @@ impl Npc {
         renderer: &DeferredRenderer,
         camera: &dyn Camera,
         theme: &GameTheme,
-        window_size: Vector2<f32>,
+        window_size: ScreenSize,
     ) {
         if self.common.entity_type != EntityType::Monster {
             return;
@@ -929,26 +956,42 @@ impl Npc {
 
         let (view_matrix, projection_matrix) = camera.view_projection_matrices();
         let clip_space_position = (projection_matrix * view_matrix) * self.common.position.extend(1.0);
-        let screen_position = Vector2::new(
-            clip_space_position.x / clip_space_position.w + 1.0,
-            clip_space_position.y / clip_space_position.w + 1.0,
-        );
+        let screen_position = ScreenPosition {
+            left: clip_space_position.x / clip_space_position.w + 1.0,
+            top: clip_space_position.y / clip_space_position.w + 1.0,
+        };
         let screen_position = screen_position / 2.0;
-        let final_position = Vector2::new(screen_position.x * window_size.x, screen_position.y * window_size.y + 5.0);
+        let final_position = ScreenPosition {
+            left: screen_position.left * window_size.width,
+            top: screen_position.top * window_size.height + 5.0,
+        };
 
         let bar_width = *theme.status_bar.enemy_bar_width;
 
         renderer.render_rectangle(
             render_target,
-            final_position - Vector2::new(theme.status_bar.border_size.x + bar_width / 2.0, theme.status_bar.border_size.y),
-            Vector2::new(bar_width, *theme.status_bar.enemy_health_height) + *theme.status_bar.border_size * 2.0,
+            final_position
+                - ScreenSize {
+                    width: theme.status_bar.border_size.x + bar_width / 2.0,
+                    height: theme.status_bar.border_size.y,
+                },
+            ScreenSize {
+                width: bar_width,
+                height: *theme.status_bar.enemy_health_height,
+            } + ScreenSize {
+                width: theme.status_bar.border_size.x * 2.0,
+                height: theme.status_bar.border_size.y * 2.0,
+            },
             *theme.status_bar.background_color,
         );
 
         renderer.render_bar(
             render_target,
             final_position,
-            Vector2::new(bar_width, *theme.status_bar.enemy_health_height),
+            ScreenSize {
+                width: bar_width,
+                height: *theme.status_bar.enemy_health_height,
+            },
             *theme.status_bar.enemy_health_color,
             self.common.maximum_health_points as f32,
             self.common.health_points as f32,
@@ -1079,7 +1122,7 @@ impl Entity {
         renderer: &DeferredRenderer,
         camera: &dyn Camera,
         theme: &GameTheme,
-        window_size: Vector2<f32>,
+        window_size: ScreenSize,
     ) {
         match self {
             Self::Player(player) => player.render_status(render_target, renderer, camera, theme, window_size),
@@ -1089,7 +1132,7 @@ impl Entity {
 }
 
 impl PrototypeWindow for Entity {
-    fn to_window(&self, window_cache: &WindowCache, interface_settings: &InterfaceSettings, available_space: Size) -> Window {
+    fn to_window(&self, window_cache: &WindowCache, interface_settings: &InterfaceSettings, available_space: ScreenSize) -> Window {
         match self {
             Entity::Player(player) => player.to_window(window_cache, interface_settings, available_space),
             Entity::Npc(npc) => npc.to_window(window_cache, interface_settings, available_space),