diff --git a/Cargo.toml b/Cargo.toml
index 10084b05c693a9bbfa63c51dc2e49fc7c72af6ed..d5ff2525e800d5425824e5f5fcb29458076cf671 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -19,6 +19,7 @@ kayak_ui_macros = { path = "./kayak_ui_macros" }
 indexmap = "1.9"
 log = "0.4"
 bitflags = "1.3.2"
+reorder = "2.1"
 
 [dev-dependencies]
 fastrand = "1.8"
diff --git a/assets/lato-light - Copy.png b/assets/lato-light - Copy.png
new file mode 100644
index 0000000000000000000000000000000000000000..103c6324efec5ccfef51aab02cde1afb0d7895ae
Binary files /dev/null and b/assets/lato-light - Copy.png differ
diff --git a/assets/lato-light.kayak_font b/assets/lato-light.kayak_font
new file mode 100644
index 0000000000000000000000000000000000000000..d82cd1ef9c9b727c57b0a06e455c794446d716ae
--- /dev/null
+++ b/assets/lato-light.kayak_font
@@ -0,0 +1 @@
+{"atlas":{"type":"msdf","distanceRange":4,"size":64,"width":384,"height":384,"yOrigin":"bottom"},"metrics":{"emSize":1,"lineHeight":1.2,"ascender":0.98699999999999999,"descender":-0.21299999999999999,"underlineY":-0.10000000000000001,"underlineThickness":0.034000000000000002},"glyphs":[{"unicode":32,"advance":0.193},{"unicode":33,"advance":0.32250000000000001,"planeBounds":{"left":0.083125000000000004,"bottom":-0.040625000000000015,"right":0.239375,"top":0.74062499999999998},"atlasBounds":{"left":359.5,"bottom":20.5,"right":369.5,"top":70.5}},{"unicode":34,"advance":0.36699999999999999,"planeBounds":{"left":0.058250000000000003,"bottom":0.43099999999999999,"right":0.30825000000000002,"top":0.74350000000000005},"atlasBounds":{"left":51.5,"bottom":312.5,"right":67.5,"top":332.5}},{"unicode":35,"advance":0.57999999999999996,"planeBounds":{"left":0.01125,"bottom":-0.036874999999999991,"right":0.57374999999999998,"top":0.74437500000000001},"atlasBounds":{"left":158.5,"bottom":179.5,"right":194.5,"top":229.5}},{"unicode":36,"advance":0.57999999999999996,"planeBounds":{"left":0.038687500000000027,"bottom":-0.16506249999999995,"right":0.55431249999999999,"top":0.8505625},"atlasBounds":{"left":232.5,"bottom":318.5,"right":265.5,"top":383.5}},{"unicode":37,"advance":0.76700000000000002,"planeBounds":{"left":0.0082499999999999969,"bottom":-0.044937500000000012,"right":0.75824999999999998,"top":0.75193750000000004},"atlasBounds":{"left":0.5,"bottom":76.5,"right":48.5,"top":127.5}},{"unicode":38,"advance":0.6915,"planeBounds":{"left":0.015937500000000004,"bottom":-0.044687499999999984,"right":0.71906250000000005,"top":0.75218750000000001},"atlasBounds":{"left":68.5,"bottom":294.5,"right":113.5,"top":345.5}},{"unicode":39,"advance":0.2215,"planeBounds":{"left":0.056062500000000008,"bottom":0.43099999999999999,"right":0.16543750000000002,"top":0.74350000000000005},"atlasBounds":{"left":0.5,"bottom":3.5,"right":7.5,"top":23.5}},{"unicode":40,"advance":0.29999999999999999,"planeBounds":{"left":0.050562500000000003,"bottom":-0.16912499999999997,"right":0.28493750000000001,"top":0.79962500000000003},"atlasBounds":{"left":51.5,"bottom":249.5,"right":66.5,"top":311.5}},{"unicode":41,"advance":0.29999999999999999,"planeBounds":{"left":0.014562500000000004,"bottom":-0.16912499999999997,"right":0.24893750000000001,"top":0.79962500000000003},"atlasBounds":{"left":51.5,"bottom":186.5,"right":66.5,"top":248.5}},{"unicode":42,"advance":0.40000000000000002,"planeBounds":{"left":0.027375000000000014,"bottom":0.41000000000000003,"right":0.37112499999999998,"top":0.78500000000000003},"atlasBounds":{"left":115.5,"bottom":2.5,"right":137.5,"top":26.5}},{"unicode":43,"advance":0.57999999999999996,"planeBounds":{"left":0.015812500000000014,"bottom":0.05350000000000002,"right":0.56268750000000001,"top":0.61599999999999999},"atlasBounds":{"left":158.5,"bottom":91.5,"right":193.5,"top":127.5}},{"unicode":44,"advance":0.19750000000000001,"planeBounds":{"left":0.021125000000000001,"bottom":-0.16137499999999999,"right":0.177375,"top":0.11987500000000001},"atlasBounds":{"left":8.5,"bottom":5.5,"right":18.5,"top":23.5}},{"unicode":45,"advance":0.33250000000000002,"planeBounds":{"left":0.017812499999999992,"bottom":0.24206250000000001,"right":0.31468750000000001,"top":0.35143750000000001},"atlasBounds":{"left":19.5,"bottom":5.5,"right":38.5,"top":12.5}},{"unicode":46,"advance":0.19750000000000001,"planeBounds":{"left":0.020625000000000001,"bottom":-0.039375,"right":0.176875,"top":0.11687500000000001},"atlasBounds":{"left":19.5,"bottom":13.5,"right":29.5,"top":23.5}},{"unicode":47,"advance":0.35649999999999998,"planeBounds":{"left":-0.03418750000000001,"bottom":-0.079124999999999959,"right":0.38768750000000002,"top":0.764625},"atlasBounds":{"left":330.5,"bottom":204.5,"right":357.5,"top":258.5}},{"unicode":48,"advance":0.57999999999999996,"planeBounds":{"left":0.00093750000000000354,"bottom":-0.044437500000000012,"right":0.57906250000000004,"top":0.75243749999999998},"atlasBounds":{"left":158.5,"bottom":230.5,"right":195.5,"top":281.5}},{"unicode":49,"advance":0.57999999999999996,"planeBounds":{"left":0.086625000000000021,"bottom":-0.03537499999999999,"right":0.55537500000000006,"top":0.74587500000000007},"atlasBounds":{"left":299.5,"bottom":295.5,"right":329.5,"top":345.5}},{"unicode":50,"advance":0.57999999999999996,"planeBounds":{"left":0.027125000000000007,"bottom":-0.032874999999999988,"right":0.55837500000000007,"top":0.74837500000000001},"atlasBounds":{"left":197.5,"bottom":246.5,"right":231.5,"top":296.5}},{"unicode":51,"advance":0.57999999999999996,"planeBounds":{"left":0.028125000000000008,"bottom":-0.044687499999999984,"right":0.55937500000000007,"top":0.75218750000000001},"atlasBounds":{"left":197.5,"bottom":194.5,"right":231.5,"top":245.5}},{"unicode":52,"advance":0.57999999999999996,"planeBounds":{"left":-0.001625000000000016,"bottom":-0.036374999999999991,"right":0.59212500000000001,"top":0.74487500000000006},"atlasBounds":{"left":115.5,"bottom":27.5,"right":153.5,"top":77.5}},{"unicode":53,"advance":0.57999999999999996,"planeBounds":{"left":0.037999999999999999,"bottom":-0.040874999999999988,"right":0.53800000000000003,"top":0.74037500000000001},"atlasBounds":{"left":232.5,"bottom":114.5,"right":264.5,"top":164.5}},{"unicode":54,"advance":0.57999999999999996,"planeBounds":{"left":0.030125000000000009,"bottom":-0.040874999999999988,"right":0.56137499999999996,"top":0.74037500000000001},"atlasBounds":{"left":197.5,"bottom":143.5,"right":231.5,"top":193.5}},{"unicode":55,"advance":0.57999999999999996,"planeBounds":{"left":0.026812500000000013,"bottom":-0.036874999999999991,"right":0.57368750000000002,"top":0.74437500000000001},"atlasBounds":{"left":158.5,"bottom":40.5,"right":193.5,"top":90.5}},{"unicode":56,"advance":0.57999999999999996,"planeBounds":{"left":0.024374999999999983,"bottom":-0.044687499999999984,"right":0.55562500000000004,"top":0.75218750000000001},"atlasBounds":{"left":197.5,"bottom":91.5,"right":231.5,"top":142.5}},{"unicode":57,"advance":0.57999999999999996,"planeBounds":{"left":0.0474375,"bottom":-0.032874999999999988,"right":0.56306250000000002,"top":0.74837500000000001},"atlasBounds":{"left":232.5,"bottom":267.5,"right":265.5,"top":317.5}},{"unicode":58,"advance":0.23750000000000002,"planeBounds":{"left":0.040625000000000001,"bottom":-0.043250000000000004,"right":0.19687499999999999,"top":0.51924999999999999},"atlasBounds":{"left":330.5,"bottom":77.5,"right":340.5,"top":113.5}},{"unicode":59,"advance":0.23750000000000002,"planeBounds":{"left":0.040625000000000001,"bottom":-0.16525000000000001,"right":0.19687499999999999,"top":0.52224999999999999},"atlasBounds":{"left":51.5,"bottom":3.5,"right":61.5,"top":47.5}},{"unicode":60,"advance":0.57999999999999996,"planeBounds":{"left":0.048750000000000002,"bottom":0.10112500000000002,"right":0.48625000000000002,"top":0.56987500000000002},"atlasBounds":{"left":330.5,"bottom":353.5,"right":358.5,"top":383.5}},{"unicode":61,"advance":0.57999999999999996,"planeBounds":{"left":0.047562500000000014,"bottom":0.20493749999999999,"right":0.53193750000000006,"top":0.47056249999999999},"atlasBounds":{"left":197.5,"bottom":6.5,"right":228.5,"top":23.5}},{"unicode":62,"advance":0.57999999999999996,"planeBounds":{"left":0.09425,"bottom":0.10112500000000002,"right":0.53175000000000006,"top":0.56987500000000002},"atlasBounds":{"left":330.5,"bottom":259.5,"right":358.5,"top":289.5}},{"unicode":63,"advance":0.3705,"planeBounds":{"left":-0.019124999999999989,"bottom":-0.044437500000000012,"right":0.387125,"top":0.75243749999999998},"atlasBounds":{"left":330.5,"bottom":152.5,"right":356.5,"top":203.5}},{"unicode":64,"advance":0.82150000000000001,"planeBounds":{"left":0.021125000000000015,"bottom":-0.15643750000000001,"right":0.80237500000000006,"top":0.70293749999999999},"atlasBounds":{"left":0.5,"bottom":277.5,"right":50.5,"top":332.5}},{"unicode":65,"advance":0.64449999999999996,"planeBounds":{"left":-0.029062500000000002,"bottom":-0.036874999999999991,"right":0.67406250000000001,"top":0.74437500000000001},"atlasBounds":{"left":68.5,"bottom":243.5,"right":113.5,"top":293.5}},{"unicode":66,"advance":0.64100000000000001,"planeBounds":{"left":0.073374999999999982,"bottom":-0.036874999999999991,"right":0.60462499999999997,"top":0.74437500000000001},"atlasBounds":{"left":197.5,"bottom":40.5,"right":231.5,"top":90.5}},{"unicode":67,"advance":0.70350000000000001,"planeBounds":{"left":0.02662500000000001,"bottom":-0.044687499999999984,"right":0.68287500000000001,"top":0.75218750000000001},"atlasBounds":{"left":68.5,"bottom":37.5,"right":110.5,"top":88.5}},{"unicode":68,"advance":0.76000000000000001,"planeBounds":{"left":0.066812500000000011,"bottom":-0.036874999999999991,"right":0.73868750000000005,"top":0.74437500000000001},"atlasBounds":{"left":68.5,"bottom":89.5,"right":111.5,"top":139.5}},{"unicode":69,"advance":0.59099999999999997,"planeBounds":{"left":0.067000000000000004,"bottom":-0.036874999999999991,"right":0.56700000000000006,"top":0.74437500000000001},"atlasBounds":{"left":266.5,"bottom":333.5,"right":298.5,"top":383.5}},{"unicode":70,"advance":0.57200000000000006,"planeBounds":{"left":0.067000000000000004,"bottom":-0.036874999999999991,"right":0.56700000000000006,"top":0.74437500000000001},"atlasBounds":{"left":232.5,"bottom":12.5,"right":264.5,"top":62.5}},{"unicode":71,"advance":0.74850000000000005,"planeBounds":{"left":0.024000000000000021,"bottom":-0.044687499999999984,"right":0.71150000000000002,"top":0.75218750000000001},"atlasBounds":{"left":68.5,"bottom":140.5,"right":112.5,"top":191.5}},{"unicode":72,"advance":0.75600000000000001,"planeBounds":{"left":0.07331250000000003,"bottom":-0.036874999999999991,"right":0.6826875,"top":0.74437500000000001},"atlasBounds":{"left":115.5,"bottom":180.5,"right":154.5,"top":230.5}},{"unicode":73,"advance":0.29899999999999999,"planeBounds":{"left":0.086750000000000008,"bottom":-0.036874999999999991,"right":0.21174999999999999,"top":0.74437500000000001},"atlasBounds":{"left":341.5,"bottom":63.5,"right":349.5,"top":113.5}},{"unicode":74,"advance":0.45400000000000001,"planeBounds":{"left":0.0092499999999999961,"bottom":-0.040874999999999988,"right":0.38424999999999998,"top":0.74037500000000001},"atlasBounds":{"left":359.5,"bottom":284.5,"right":383.5,"top":334.5}},{"unicode":75,"advance":0.66000000000000003,"planeBounds":{"left":0.083874999999999991,"bottom":-0.036374999999999991,"right":0.67762500000000003,"top":0.74487500000000006},"atlasBounds":{"left":158.5,"bottom":333.5,"right":196.5,"top":383.5}},{"unicode":76,"advance":0.51150000000000007,"planeBounds":{"left":0.071687500000000001,"bottom":-0.036874999999999991,"right":0.52481250000000002,"top":0.74437500000000001},"atlasBounds":{"left":299.5,"bottom":102.5,"right":328.5,"top":152.5}},{"unicode":77,"advance":0.90900000000000003,"planeBounds":{"left":0.071687500000000029,"bottom":-0.036874999999999991,"right":0.83731250000000002,"top":0.74437500000000001},"atlasBounds":{"left":0.5,"bottom":128.5,"right":49.5,"top":178.5}},{"unicode":78,"advance":0.75600000000000001,"planeBounds":{"left":0.07331250000000003,"bottom":-0.036874999999999991,"right":0.6826875,"top":0.74437500000000001},"atlasBounds":{"left":115.5,"bottom":129.5,"right":154.5,"top":179.5}},{"unicode":79,"advance":0.79749999999999999,"planeBounds":{"left":0.023749999999999993,"bottom":-0.044437500000000012,"right":0.77375000000000005,"top":0.75243749999999998},"atlasBounds":{"left":0.5,"bottom":24.5,"right":48.5,"top":75.5}},{"unicode":80,"advance":0.59350000000000003,"planeBounds":{"left":0.086750000000000008,"bottom":-0.036874999999999991,"right":0.58674999999999999,"top":0.74437500000000001},"atlasBounds":{"left":232.5,"bottom":63.5,"right":264.5,"top":113.5}},{"unicode":81,"advance":0.79749999999999999,"planeBounds":{"left":0.022625000000000006,"bottom":-0.18899999999999997,"right":0.80387500000000001,"top":0.74850000000000005},"atlasBounds":{"left":0.5,"bottom":216.5,"right":50.5,"top":276.5}},{"unicode":82,"advance":0.63100000000000001,"planeBounds":{"left":0.082750000000000004,"bottom":-0.036874999999999991,"right":0.64524999999999999,"top":0.74437500000000001},"atlasBounds":{"left":158.5,"bottom":128.5,"right":194.5,"top":178.5}},{"unicode":83,"advance":0.52249999999999996,"planeBounds":{"left":0.01125,"bottom":-0.044687499999999984,"right":0.51124999999999998,"top":0.75218750000000001},"atlasBounds":{"left":232.5,"bottom":165.5,"right":264.5,"top":216.5}},{"unicode":84,"advance":0.58450000000000002,"planeBounds":{"left":-0.020250000000000008,"bottom":-0.036874999999999991,"right":0.60475000000000001,"top":0.74437500000000001},"atlasBounds":{"left":115.5,"bottom":231.5,"right":155.5,"top":281.5}},{"unicode":85,"advance":0.73350000000000004,"planeBounds":{"left":0.061812500000000013,"bottom":-0.041125000000000016,"right":0.67118750000000005,"top":0.74012500000000003},"atlasBounds":{"left":115.5,"bottom":78.5,"right":154.5,"top":128.5}},{"unicode":86,"advance":0.64449999999999996,"planeBounds":{"left":-0.029312499999999971,"bottom":-0.036874999999999991,"right":0.67381250000000004,"top":0.74437500000000001},"atlasBounds":{"left":68.5,"bottom":192.5,"right":113.5,"top":242.5}},{"unicode":87,"advance":0.98699999999999999,"planeBounds":{"left":-0.030187499999999985,"bottom":-0.036874999999999991,"right":1.0166875,"top":0.74437500000000001},"atlasBounds":{"left":0.5,"bottom":333.5,"right":67.5,"top":383.5}},{"unicode":88,"advance":0.59950000000000003,"planeBounds":{"left":-0.028625000000000022,"bottom":-0.036874999999999991,"right":0.62762499999999999,"top":0.74437500000000001},"atlasBounds":{"left":115.5,"bottom":333.5,"right":157.5,"top":383.5}},{"unicode":89,"advance":0.59950000000000003,"planeBounds":{"left":-0.020562499999999994,"bottom":-0.036874999999999991,"right":0.62006249999999996,"top":0.74437500000000001},"atlasBounds":{"left":115.5,"bottom":282.5,"right":156.5,"top":332.5}},{"unicode":90,"advance":0.63300000000000001,"planeBounds":{"left":0.02262500000000001,"bottom":-0.036874999999999991,"right":0.61637500000000001,"top":0.74437500000000001},"atlasBounds":{"left":158.5,"bottom":282.5,"right":196.5,"top":332.5}},{"unicode":91,"advance":0.29999999999999999,"planeBounds":{"left":0.049812500000000003,"bottom":-0.16331249999999997,"right":0.28418749999999998,"top":0.78981250000000003},"atlasBounds":{"left":51.5,"bottom":124.5,"right":66.5,"top":185.5}},{"unicode":92,"advance":0.35749999999999998,"planeBounds":{"left":-0.035687500000000011,"bottom":-0.079124999999999959,"right":0.38618750000000002,"top":0.764625},"atlasBounds":{"left":266.5,"bottom":0.5,"right":293.5,"top":54.5}},{"unicode":93,"advance":0.29999999999999999,"planeBounds":{"left":0.015562500000000002,"bottom":-0.16331249999999997,"right":0.24993750000000001,"top":0.78981250000000003},"atlasBounds":{"left":51.5,"bottom":62.5,"right":66.5,"top":123.5}},{"unicode":94,"advance":0.57999999999999996,"planeBounds":{"left":0.068250000000000005,"bottom":0.36625000000000002,"right":0.50575000000000003,"top":0.74124999999999996},"atlasBounds":{"left":330.5,"bottom":328.5,"right":358.5,"top":352.5}},{"unicode":95,"advance":0.39400000000000002,"planeBounds":{"left":-0.037374999999999992,"bottom":-0.1741875,"right":0.43137500000000001,"top":-0.064812499999999995},"atlasBounds":{"left":232.5,"bottom":4.5,"right":262.5,"top":11.5}},{"unicode":96,"advance":0.29249999999999998,"planeBounds":{"left":0.010625000000000001,"bottom":0.54643750000000002,"right":0.229375,"top":0.74956250000000002},"atlasBounds":{"left":51.5,"bottom":48.5,"right":65.5,"top":61.5}},{"unicode":97,"advance":0.48649999999999999,"planeBounds":{"left":0.016749999999999994,"bottom":-0.040062499999999994,"right":0.45424999999999999,"top":0.5380625},"atlasBounds":{"left":330.5,"bottom":290.5,"right":358.5,"top":327.5}},{"unicode":98,"advance":0.54600000000000004,"planeBounds":{"left":0.052062500000000018,"bottom":-0.037937500000000006,"right":0.53643750000000001,"top":0.75893750000000004},"atlasBounds":{"left":266.5,"bottom":232.5,"right":297.5,"top":283.5}},{"unicode":99,"advance":0.45500000000000002,"planeBounds":{"left":0.0094375000000000032,"bottom":-0.039562499999999994,"right":0.46256249999999999,"top":0.53856250000000006},"atlasBounds":{"left":299.5,"bottom":205.5,"right":328.5,"top":242.5}},{"unicode":100,"advance":0.54600000000000004,"planeBounds":{"left":0.0095625000000000172,"bottom":-0.037937500000000006,"right":0.49393750000000003,"top":0.75893750000000004},"atlasBounds":{"left":266.5,"bottom":142.5,"right":297.5,"top":193.5}},{"unicode":101,"advance":0.51100000000000001,"planeBounds":{"left":0.011812499999999993,"bottom":-0.039562499999999994,"right":0.4961875,"top":0.53856250000000006},"atlasBounds":{"left":266.5,"bottom":194.5,"right":297.5,"top":231.5}},{"unicode":102,"advance":0.32200000000000001,"planeBounds":{"left":-0.016687500000000008,"bottom":-0.032374999999999987,"right":0.34268750000000003,"top":0.74887500000000007},"atlasBounds":{"left":359.5,"bottom":195.5,"right":382.5,"top":245.5}},{"unicode":103,"advance":0.50450000000000006,"planeBounds":{"left":0.0021875000000000319,"bottom":-0.2225625,"right":0.51781250000000001,"top":0.5430625},"atlasBounds":{"left":232.5,"bottom":217.5,"right":265.5,"top":266.5}},{"unicode":104,"advance":0.54100000000000004,"planeBounds":{"left":0.04212500000000001,"bottom":-0.034687499999999989,"right":0.51087499999999997,"top":0.76218750000000002},"atlasBounds":{"left":299.5,"bottom":243.5,"right":329.5,"top":294.5}},{"unicode":105,"advance":0.23750000000000002,"planeBounds":{"left":0.041125000000000002,"bottom":-0.033874999999999988,"right":0.19737499999999999,"top":0.74737500000000001},"atlasBounds":{"left":330.5,"bottom":26.5,"right":340.5,"top":76.5}},{"unicode":106,"advance":0.23550000000000001,"planeBounds":{"left":-0.063562500000000008,"bottom":-0.21987500000000001,"right":0.20206250000000001,"top":0.74887500000000007},"atlasBounds":{"left":307.5,"bottom":2.5,"right":324.5,"top":64.5}},{"unicode":107,"advance":0.49199999999999999,"planeBounds":{"left":0.050437500000000003,"bottom":-0.034687499999999989,"right":0.50356250000000002,"top":0.76218750000000002},"atlasBounds":{"left":299.5,"bottom":153.5,"right":328.5,"top":204.5}},{"unicode":108,"advance":0.23750000000000002,"planeBounds":{"left":0.056250000000000001,"bottom":-0.034687499999999989,"right":0.18124999999999999,"top":0.76218750000000002},"atlasBounds":{"left":341.5,"bottom":11.5,"right":349.5,"top":62.5}},{"unicode":109,"advance":0.79549999999999998,"planeBounds":{"left":0.044625000000000005,"bottom":-0.03631249999999997,"right":0.76337500000000003,"top":0.54181250000000003},"atlasBounds":{"left":68.5,"bottom":346.5,"right":114.5,"top":383.5}},{"unicode":110,"advance":0.54100000000000004,"planeBounds":{"left":0.04212500000000001,"bottom":-0.03631249999999997,"right":0.51087499999999997,"top":0.54181250000000003},"atlasBounds":{"left":299.5,"bottom":346.5,"right":329.5,"top":383.5}},{"unicode":111,"advance":0.54100000000000004,"planeBounds":{"left":0.0046250000000000076,"bottom":-0.039562499999999994,"right":0.53587499999999999,"top":0.53856250000000006},"atlasBounds":{"left":197.5,"bottom":297.5,"right":231.5,"top":334.5}},{"unicode":112,"advance":0.53500000000000003,"planeBounds":{"left":0.046812500000000014,"bottom":-0.20999999999999996,"right":0.53118750000000003,"top":0.54000000000000004},"atlasBounds":{"left":266.5,"bottom":284.5,"right":297.5,"top":332.5}},{"unicode":113,"advance":0.54600000000000004,"planeBounds":{"left":0.0095625000000000172,"bottom":-0.20999999999999996,"right":0.49393750000000003,"top":0.54000000000000004},"atlasBounds":{"left":266.5,"bottom":93.5,"right":297.5,"top":141.5}},{"unicode":114,"advance":0.39700000000000002,"planeBounds":{"left":0.044062500000000018,"bottom":-0.036062499999999997,"right":0.4034375,"top":0.5420625},"atlasBounds":{"left":359.5,"bottom":246.5,"right":382.5,"top":283.5}},{"unicode":115,"advance":0.42999999999999999,"planeBounds":{"left":0.0078750000000000087,"bottom":-0.040312499999999966,"right":0.41412500000000002,"top":0.53781250000000003},"atlasBounds":{"left":330.5,"bottom":114.5,"right":356.5,"top":151.5}},{"unicode":116,"advance":0.35649999999999998,"planeBounds":{"left":-0.011500000000000007,"bottom":-0.042999999999999976,"right":0.36349999999999999,"top":0.70699999999999996},"atlasBounds":{"left":359.5,"bottom":335.5,"right":383.5,"top":383.5}},{"unicode":117,"advance":0.54100000000000004,"planeBounds":{"left":0.029875000000000009,"bottom":-0.04431249999999997,"right":0.49862499999999998,"top":0.53381250000000002},"atlasBounds":{"left":266.5,"bottom":55.5,"right":296.5,"top":92.5}},{"unicode":118,"advance":0.48699999999999999,"planeBounds":{"left":-0.022125000000000016,"bottom":-0.032499999999999973,"right":0.50912500000000005,"top":0.53000000000000003},"atlasBounds":{"left":158.5,"bottom":3.5,"right":192.5,"top":39.5}},{"unicode":119,"advance":0.73699999999999999,"planeBounds":{"left":-0.022125000000000016,"bottom":-0.03125,"right":0.75912500000000005,"top":0.53125},"atlasBounds":{"left":0.5,"bottom":179.5,"right":50.5,"top":215.5}},{"unicode":120,"advance":0.46050000000000002,"planeBounds":{"left":-0.019750000000000007,"bottom":-0.032499999999999973,"right":0.48025000000000001,"top":0.53000000000000003},"atlasBounds":{"left":68.5,"bottom":0.5,"right":100.5,"top":36.5}},{"unicode":121,"advance":0.48699999999999999,"planeBounds":{"left":-0.022374999999999985,"bottom":-0.21425,"right":0.50887499999999997,"top":0.53575000000000006},"atlasBounds":{"left":197.5,"bottom":335.5,"right":231.5,"top":383.5}},{"unicode":122,"advance":0.45200000000000001,"planeBounds":{"left":-0.0015625000000000001,"bottom":-0.032499999999999973,"right":0.45156250000000003,"top":0.53000000000000003},"atlasBounds":{"left":299.5,"bottom":65.5,"right":328.5,"top":101.5}},{"unicode":123,"advance":0.29999999999999999,"planeBounds":{"left":-0.0011249999999999876,"bottom":-0.16331249999999997,"right":0.28012500000000001,"top":0.78981250000000003},"atlasBounds":{"left":359.5,"bottom":133.5,"right":377.5,"top":194.5}},{"unicode":124,"advance":0.29999999999999999,"planeBounds":{"left":0.095062500000000008,"bottom":-0.20874999999999999,"right":0.20443749999999999,"top":0.79125000000000001},"atlasBounds":{"left":299.5,"bottom":0.5,"right":306.5,"top":64.5}},{"unicode":125,"advance":0.29999999999999999,"planeBounds":{"left":0.019625000000000014,"bottom":-0.16331249999999997,"right":0.300875,"top":0.78981250000000003},"atlasBounds":{"left":359.5,"bottom":71.5,"right":377.5,"top":132.5}},{"unicode":126,"advance":0.57999999999999996,"planeBounds":{"left":0.032187500000000029,"bottom":0.17806250000000001,"right":0.54781250000000004,"top":0.41243750000000001},"atlasBounds":{"left":197.5,"bottom":24.5,"right":230.5,"top":39.5}}],"kerning":[]}
diff --git a/assets/lato-light.png b/assets/lato-light.png
new file mode 100644
index 0000000000000000000000000000000000000000..c0810e29b4cec4bcc92c8184cc1177386676d901
Binary files /dev/null and b/assets/lato-light.png differ
diff --git a/book/src/chapter_1.md b/book/src/chapter_1.md
index 9ced7890ffa74c734a26a83b0fbd783dc8fdf6e2..419a831e8cc512470796b046c890b72cb608f99f 100644
--- a/book/src/chapter_1.md
+++ b/book/src/chapter_1.md
@@ -69,13 +69,7 @@ fn startup(
     commands.spawn(UICameraBundle::new());
     let mut widget_context = KayakRootContext::new();
 
-    let pre_existing_app_entity = widget_context.get_child_at(None);
-    let app_entity = if let Some(entity) = pre_existing_app_entity {
-        commands.get_or_spawn(entity).id()
-    } else {
-        commands.spawn_empty().id()
-    };
-
+    let app_entity = widget_context.spawn_widget(&mut commands, None);
     // Create default app bundle
     let mut app_bundle = KayakAppBundle {
         ..Default::default()
@@ -85,12 +79,7 @@ fn startup(
     let mut children = KChildren::new();
 
     // Create the text child
-    let pre_existing_text_entity = widget_context.get_child_at(Some(app_entity));
-    let text_entity = if let Some(entity) = pre_existing_text_entity {
-        commands.get_or_spawn(entity).id()
-    } else {
-        commands.spawn_empty().id()
-    };
+    let text_entity = widget_context.spawn_widget(&mut commands, Some(app_entity));
     commands.entity(text_entity).insert(TextWidgetBundle {
         text: TextProps {
             content: "Hello World".into(),
@@ -113,10 +102,11 @@ fn startup(
 }
 fn main() {
     App::new()
-        .add_plugins(DefaultPlugins.set(ImagePlugin::default_nearest()))
+        .add_plugins(DefaultPlugins)
         .add_plugin(KayakContextPlugin)
         .add_plugin(KayakWidgets)
         .add_startup_system(startup)
         .run()
 }
+
 ```
diff --git a/examples/bevy_scene.rs b/examples/bevy_scene.rs
index 68a6568751efd5805af1a19f47d5a58e9a56855a..dc9f9663f09e15d99157fa6bacdeeaf96ad08be9 100644
--- a/examples/bevy_scene.rs
+++ b/examples/bevy_scene.rs
@@ -227,29 +227,28 @@ fn startup(
                     text={TextProps {
                         size: 13.0,
                         content: "You can check if the cursor is over the UI or on a focusable widget using the BevyContext resource.".to_string(),
+                        user_styles: text_styles.clone(),
                         ..Default::default()
                     }}
-                    styles={text_styles.clone()}
                 />
                 <KButtonBundle
+                    button={KButton {
+                        text: "Change Tile Color".into(),
+                        ..Default::default()
+                    }}
                     on_event={handle_change_color}
                     styles={button_styles}
-                >
-                    <TextWidgetBundle
-                        text={TextProps {
-                            size: 16.0,
-                            content: "Change Tile Color".to_string(),
-                            ..Default::default()
-                        }}
-                    />
-                </KButtonBundle>
+                />
                 <TextWidgetBundle
                     text={TextProps {
                         size: 11.0,
                         content: "Go ahead and click the button! The tile won't move.".to_string(),
+                        user_styles: KStyle {
+                            top: Units::Pixels(10.0).into(),
+                            ..text_styles
+                        },
                         ..Default::default()
                     }}
-                    styles={text_styles}
                 />
             </WindowBundle>
         </KayakAppBundle>
diff --git a/examples/conditional_widget.rs b/examples/conditional_widget.rs
new file mode 100644
index 0000000000000000000000000000000000000000..a6de4d662b0dcc7e9fa79b595a9c8c38a45e39f7
--- /dev/null
+++ b/examples/conditional_widget.rs
@@ -0,0 +1,143 @@
+use bevy::prelude::*;
+use kayak_ui::prelude::{widgets::*, *};
+
+#[derive(Component, Default, PartialEq, Clone)]
+struct MyWidget;
+
+impl Widget for MyWidget {}
+
+#[derive(Component, Default, PartialEq, Clone)]
+struct MyWidgetState {
+    pub show_window: bool,
+}
+
+#[derive(Bundle)]
+struct MyWidgetBundle {
+    count: MyWidget,
+    styles: KStyle,
+    widget_name: WidgetName,
+}
+
+impl Default for MyWidgetBundle {
+    fn default() -> Self {
+        Self {
+            count: MyWidget::default(),
+            styles: KStyle::default(),
+            widget_name: MyWidget::default().get_name(),
+        }
+    }
+}
+
+fn my_widget_render(
+    In((widget_context, entity)): In<(KayakWidgetContext, Entity)>,
+    mut commands: Commands,
+    query: Query<&MyWidgetState>,
+) -> bool {
+    let state_entity = widget_context.use_state(&mut commands, entity, MyWidgetState::default());
+    if let Ok(state) = query.get(state_entity) {
+        let parent_id = Some(entity);
+        rsx! {
+            <ElementBundle>
+                <KButtonBundle
+                    button={KButton {
+                        text: "Show Window".into(),
+                        user_styles: KStyle {
+                            left: Units::Stretch(1.0).into(),
+                            right: Units::Stretch(1.0).into(),
+                            ..Default::default()
+                        }
+                    }}
+                    on_event={OnEvent::new(
+                        move |In((event_dispatcher_context, _, mut event, _entity)): In<(EventDispatcherContext, WidgetState, Event, Entity)>,
+                            mut query: Query<&mut MyWidgetState>| {
+                            event.prevent_default();
+                            event.stop_propagation();
+                            match event.event_type {
+                                EventType::Click(..) => {
+                                    if let Ok(mut state) = query.get_mut(state_entity) {
+                                        state.show_window = true;
+                                    }
+                                }
+                                _ => {}
+                            }
+                            (event_dispatcher_context, event)
+                        },
+                    )}
+                />
+                {if state.show_window {
+                    constructor! {
+                        <WindowBundle
+                            window={KWindow {
+                                title: "Conditional widget rendering!".into(),
+                                draggable: true,
+                                initial_position: Vec2::new(10.0, 10.0),
+                                size: Vec2::new(300.0, 250.0),
+                                ..KWindow::default()
+                            }}
+                        >
+                            <KButtonBundle
+                                button={KButton { text: "Hide Window".into(), ..Default::default() }}
+                                on_event={OnEvent::new(
+                                    move |In((event_dispatcher_context, _, mut event, _entity)): In<(EventDispatcherContext, WidgetState, Event, Entity)>,
+                                        mut query: Query<&mut MyWidgetState>| {
+                                        match event.event_type {
+                                            EventType::Click(..) => {
+                                                event.prevent_default();
+                                                event.stop_propagation();
+                                                if let Ok(mut state) = query.get_mut(state_entity) {
+                                                    state.show_window = false;
+                                                }
+                                            }
+                                            _ => {}
+                                        }
+                                        (event_dispatcher_context, event)
+                                    },
+                                )}
+                            />
+                        </WindowBundle>
+                    }
+                }}
+            </ElementBundle>
+        }
+    }
+
+    true
+}
+
+fn startup(
+    mut commands: Commands,
+    mut font_mapping: ResMut<FontMapping>,
+    asset_server: Res<AssetServer>,
+) {
+    font_mapping.set_default(asset_server.load("lato-light.kayak_font"));
+
+    // Camera 2D forces a clear pass in bevy.
+    // We do this because our scene is not rendering anything else.
+    commands.spawn(Camera2dBundle::default());
+    commands.spawn(UICameraBundle::new());
+
+    let mut widget_context = KayakRootContext::new();
+    let parent_id = None;
+    widget_context.add_widget_data::<MyWidget, MyWidgetState>();
+    widget_context.add_widget_system(
+        MyWidget::default().get_name(),
+        widget_update::<MyWidget, MyWidgetState>,
+        my_widget_render,
+    );
+    rsx! {
+        <KayakAppBundle>
+            <MyWidgetBundle />
+        </KayakAppBundle>
+    }
+    commands.insert_resource(widget_context);
+}
+
+fn main() {
+    App::new()
+        .insert_resource(ClearColor(Color::rgb(0.0, 0.0, 0.0)))
+        .add_plugins(DefaultPlugins)
+        .add_plugin(KayakContextPlugin)
+        .add_plugin(KayakWidgets)
+        .add_startup_system(startup)
+        .run()
+}
diff --git a/examples/context.rs b/examples/context.rs
index 5630b1fb4ee9938a5b2cac6c7ae4acfd18ec3634..bc128dfe17388b00fe1fc8541bf0f0d9f76be892 100644
--- a/examples/context.rs
+++ b/examples/context.rs
@@ -255,18 +255,17 @@ fn update_theme_demo(
                 };
 
                 let parent_id = Some(entity);
-                let mut children = kayak_ui::prelude::KChildren::new();
                 rsx! {
-                    <>
+                    <ElementBundle>
                         <TextWidgetBundle
                             text={TextProps {
                                 content: select_lbl,
                                 size: 14.0,
                                 line_height: Some(28.0),
-                                ..Default::default()
-                            }}
-                            styles={KStyle {
-                                height: StyleProp::Value(Units::Pixels(28.0)),
+                                user_styles: KStyle {
+                                    height: StyleProp::Value(Units::Pixels(28.0)),
+                                    ..Default::default()
+                                },
                                 ..Default::default()
                             }}
                         />
@@ -284,21 +283,14 @@ fn update_theme_demo(
                                 text={TextProps {
                                     content: "Lorem ipsum dolor...".into(),
                                     size: 12.0,
+                                    user_styles: text_styles.clone(),
                                     ..Default::default()
                                 }}
-                                styles={text_styles.clone()}
                             />
                             <KButtonBundle
+                                button={KButton { text: "BUTTON".into(), ..Default::default() }}
                                 styles={btn_style.clone()}
-                            >
-                                <TextWidgetBundle
-                                    text={TextProps {
-                                        content: "BUTTON".into(),
-                                        size: 14.0,
-                                        ..Default::default()
-                                    }}
-                                />
-                            </KButtonBundle>
+                            />
                             {
                                 if theme_demo.is_root {
                                     widget_context.set_context_entity::<Theme>(
@@ -321,10 +313,8 @@ fn update_theme_demo(
                                 }
                             }
                         </BackgroundBundle>
-                    </>
+                    </ElementBundle>
                 }
-
-                children.process(&widget_context, parent_id);
             }
         }
     }
diff --git a/examples/hello_world_no_macro.rs b/examples/hello_world_no_macro.rs
index 02192bd40bff8da9f1a3b7ec24ba02ac7080eb0f..647e31db7f387e8a0b2710ef869f6e15222e8389 100644
--- a/examples/hello_world_no_macro.rs
+++ b/examples/hello_world_no_macro.rs
@@ -9,13 +9,7 @@ fn startup(
     commands.spawn(UICameraBundle::new());
     let mut widget_context = KayakRootContext::new();
 
-    let pre_existing_app_entity = widget_context.get_child_at(None);
-    let app_entity = if let Some(entity) = pre_existing_app_entity {
-        commands.get_or_spawn(entity).id()
-    } else {
-        commands.spawn_empty().id()
-    };
-
+    let app_entity = widget_context.spawn_widget(&mut commands, None);
     // Create default app bundle
     let mut app_bundle = KayakAppBundle {
         ..Default::default()
@@ -25,12 +19,7 @@ fn startup(
     let mut children = KChildren::new();
 
     // Create the text child
-    let pre_existing_text_entity = widget_context.get_child_at(Some(app_entity));
-    let text_entity = if let Some(entity) = pre_existing_text_entity {
-        commands.get_or_spawn(entity).id()
-    } else {
-        commands.spawn_empty().id()
-    };
+    let text_entity = widget_context.spawn_widget(&mut commands, Some(app_entity));
     commands.entity(text_entity).insert(TextWidgetBundle {
         text: TextProps {
             content: "Hello World".into(),
diff --git a/examples/quads.rs b/examples/quads.rs
index 514c9a9b88a442164460ef2ed64d81807959a48d..5e6523107cc2ecd3aff5dc1ada1fb9717cf7652b 100644
--- a/examples/quads.rs
+++ b/examples/quads.rs
@@ -9,6 +9,7 @@ pub struct MyQuad {
     pos: Vec2,
     pub size: Vec2,
     pub color: Color,
+    pub z_index: i32,
 }
 
 fn my_quad_update(
@@ -24,16 +25,19 @@ fn my_quad_update(
             style.width = StyleProp::Value(Units::Pixels(quad.size.x));
             style.height = StyleProp::Value(Units::Pixels(quad.size.y));
             style.background_color = StyleProp::Value(quad.color);
+            style.z_index = StyleProp::Value(quad.z_index);
         }
 
         *on_event = OnEvent::new(
-            move |In((event_dispatcher_context, _, event, entity)): In<(
+            move |In((event_dispatcher_context, _, mut event, entity)): In<(
                 EventDispatcherContext,
                 WidgetState,
                 Event,
                 Entity,
             )>,
                   mut query: Query<(&mut KStyle, &MyQuad)>| {
+                event.prevent_default();
+                event.stop_propagation();
                 match event.event_type {
                     EventType::MouseIn(..) => {
                         if let Ok((mut styles, _)) = query.get_mut(entity) {
@@ -99,7 +103,7 @@ fn startup(
     rsx! {
         <KayakAppBundle>
             {
-                (0..1000).for_each(|_| {
+                (0..1000i32).for_each(|i| {
                     let pos = Vec2::new(fastrand::i32(0..1280) as f32, fastrand::i32(0..720) as f32);
                     let size = Vec2::new(
                         fastrand::i32(32..64) as f32,
@@ -113,7 +117,7 @@ fn startup(
                     );
                     constructor! {
                         <MyQuadBundle
-                            my_quad={MyQuad { pos, size, color }}
+                            my_quad={MyQuad { pos, size, color, z_index: i }}
                         />
                     }
                 });
diff --git a/examples/scrolling.rs b/examples/scrolling.rs
index 6c87b1b662266b4786278e69df4029146b7206ae..baef12e0230ffbca9b0d17c29ff47b0bd0546deb 100644
--- a/examples/scrolling.rs
+++ b/examples/scrolling.rs
@@ -1,5 +1,5 @@
 use bevy::prelude::*;
-use kayak_ui::prelude::{widgets::*, KStyle, *};
+use kayak_ui::prelude::{widgets::*, *};
 
 fn startup(
     mut commands: Commands,
@@ -8,21 +8,14 @@ fn startup(
 ) {
     font_mapping.set_default(asset_server.load("roboto.kayak_font"));
 
+    // Camera 2D forces a clear pass in bevy.
+    // We do this because our scene is not rendering anything else.
+    commands.spawn(Camera2dBundle::default());
     commands.spawn(UICameraBundle::new());
 
-    let image = asset_server.load("kenny/panel_brown.png");
-
     let mut widget_context = KayakRootContext::new();
     let parent_id = None;
 
-    let nine_patch_styles = KStyle {
-        width: StyleProp::Value(Units::Pixels(512.0)),
-        height: StyleProp::Value(Units::Pixels(512.0)),
-        offset: StyleProp::Value(Edge::all(Units::Stretch(1.0))),
-        padding: StyleProp::Value(Edge::all(Units::Pixels(25.0))),
-        ..KStyle::default()
-    };
-
     let lorem_ipsum = r#"
 Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras sed tellus neque. Proin tempus ligula a mi molestie aliquam. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nullam venenatis consequat ultricies. Sed ac orci purus. Nullam velit nisl, dapibus vel mauris id, dignissim elementum sapien. Vestibulum faucibus sapien ut erat bibendum, id lobortis nisi luctus. Mauris feugiat at lectus at pretium. Pellentesque vitae finibus ante. Nulla non ex neque. Cras varius, lorem facilisis consequat blandit, lorem mauris mollis massa, eget consectetur magna sem vel enim. Nam aliquam risus pulvinar, volutpat leo eget, eleifend urna. Suspendisse in magna sed ligula vehicula volutpat non vitae augue. Phasellus aliquam viverra consequat. Nam rhoncus molestie purus, sed laoreet neque imperdiet eget. Sed egestas metus eget sodales congue.
                                     
@@ -37,12 +30,14 @@ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras sed tellus neque.
 
     rsx! {
         <KayakAppBundle>
-            <NinePatchBundle
-                nine_patch={NinePatch {
-                    handle: image.clone(),
-                    border: Edge::all(30.0),
+            <WindowBundle
+                window={KWindow {
+                    title: "Simple scrolling example".into(),
+                    draggable: true,
+                    initial_position: Vec2::new(10.0, 10.0),
+                    size: Vec2::new(512.0, 512.0),
+                    ..KWindow::default()
                 }}
-                styles={nine_patch_styles}
             >
                 <ScrollContextProviderBundle>
                     <ScrollBoxBundle>
@@ -55,7 +50,7 @@ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras sed tellus neque.
                         />
                     </ScrollBoxBundle>
                 </ScrollContextProviderBundle>
-            </NinePatchBundle>
+            </WindowBundle>
         </KayakAppBundle>
     }
     commands.insert_resource(widget_context);
@@ -63,6 +58,7 @@ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras sed tellus neque.
 
 fn main() {
     App::new()
+        .insert_resource(ClearColor(Color::rgb(0.0, 0.0, 0.0)))
         .add_plugins(DefaultPlugins.set(ImagePlugin::default_nearest()))
         .add_plugin(KayakContextPlugin)
         .add_plugin(KayakWidgets)
diff --git a/examples/simple_state.rs b/examples/simple_state.rs
index eee326a6c2d91654447d0982dcee3d283d9721f3..e55f5b202b372b42296abc44c09f1d5b4fed378d 100644
--- a/examples/simple_state.rs
+++ b/examples/simple_state.rs
@@ -38,22 +38,44 @@ fn current_count_render(
     if let Ok(current_count) = query.get(state_entity) {
         let parent_id = Some(entity);
         rsx! {
-            <TextWidgetBundle
-                text={
-                    TextProps {
-                        content: format!("Current Count: {}", current_count.foo).into(),
-                        size: 16.0,
-                        line_height: Some(40.0),
-                        ..Default::default()
+            <ElementBundle>
+                <TextWidgetBundle
+                    text={
+                        TextProps {
+                            content: format!("Current Count: {}", current_count.foo).into(),
+                            size: 16.0,
+                            line_height: Some(40.0),
+                            ..Default::default()
+                        }
                     }
-                }
-            />
+                />
+                <KButtonBundle
+                    button={KButton {
+                        text: "Click me!".into(),
+                        ..Default::default()
+                    }}
+                    on_event={OnEvent::new(
+                        move |In((event_dispatcher_context, _, mut event, _entity)): In<(EventDispatcherContext, WidgetState, Event, Entity)>,
+                            mut query: Query<&mut CurrentCountState>| {
+                            match event.event_type {
+                                EventType::Click(..) => {
+                                    event.prevent_default();
+                                    event.stop_propagation();
+                                    if let Ok(mut current_count) = query.get_mut(state_entity) {
+                                        current_count.foo += 1;
+                                    }
+                                }
+                                _ => {}
+                            }
+                            (event_dispatcher_context, event)
+                        },
+                    )}
+                />
+            </ElementBundle>
         }
-
-        return true;
     }
 
-    false
+    true
 }
 
 fn startup(
@@ -61,7 +83,7 @@ fn startup(
     mut font_mapping: ResMut<FontMapping>,
     asset_server: Res<AssetServer>,
 ) {
-    font_mapping.set_default(asset_server.load("roboto.kayak_font"));
+    font_mapping.set_default(asset_server.load("lato-light.kayak_font"));
 
     // Camera 2D forces a clear pass in bevy.
     // We do this because our scene is not rendering anything else.
@@ -78,44 +100,30 @@ fn startup(
     );
     rsx! {
         <KayakAppBundle>
-            <WindowBundle
-                window={KWindow {
-                    title: "State Example Window".into(),
-                    draggable: true,
-                    initial_position: Vec2::new(10.0, 10.0),
-                    size: Vec2::new(300.0, 250.0),
-                    ..KWindow::default()
-                }}
-            >
-                <CurrentCountBundle id={"current_count_entity"} />
-                <KButtonBundle
-                    on_event={OnEvent::new(
-                        move |In((event_dispatcher_context, widget_state, event, _entity)): In<(EventDispatcherContext, WidgetState, Event, Entity)>,
-                            mut query: Query<&mut CurrentCountState>| {
-                            match event.event_type {
-                                EventType::Click(..) => {
-                                    if let Some(state_entity) = widget_state.get(current_count_entity) {
-                                        if let Ok(mut current_count) = query.get_mut(state_entity) {
-                                            current_count.foo += 1;
-                                        }
-                                    }
-                                }
-                                _ => {}
-                            }
-                            (event_dispatcher_context, event)
-                        },
-                    )}
+            <WindowContextProviderBundle>
+                <WindowBundle
+                    window={KWindow {
+                        title: "State Example Window".into(),
+                        draggable: true,
+                        initial_position: Vec2::new(10.0, 10.0),
+                        size: Vec2::new(300.0, 250.0),
+                        ..KWindow::default()
+                    }}
                 >
-                    <TextWidgetBundle
-                        text={TextProps {
-                            content: "Click me!".into(),
-                            size: 16.0,
-                            alignment: Alignment::Start,
-                            ..Default::default()
-                        }}
-                    />
-                </KButtonBundle>
-            </WindowBundle>
+                    <CurrentCountBundle />
+                </WindowBundle>
+                <WindowBundle
+                    window={KWindow {
+                        title: "State Example Window".into(),
+                        draggable: true,
+                        initial_position: Vec2::new(500.0, 10.0),
+                        size: Vec2::new(300.0, 250.0),
+                        ..KWindow::default()
+                    }}
+                >
+                    <CurrentCountBundle />
+                </WindowBundle>
+            </WindowContextProviderBundle>
         </KayakAppBundle>
     }
     commands.insert_resource(widget_context);
diff --git a/examples/tabs/tab.rs b/examples/tabs/tab.rs
index 4088274e824e777cf26cb2c2fcfaa35f73832e5f..1260842d374dfce9ed176cd36c398f7e9dbecdd9 100644
--- a/examples/tabs/tab.rs
+++ b/examples/tabs/tab.rs
@@ -16,7 +16,6 @@ impl Widget for Tab {}
 #[derive(Bundle)]
 pub struct TabBundle {
     pub tab: Tab,
-    pub styles: KStyle,
     pub children: KChildren,
     pub widget_name: WidgetName,
 }
@@ -26,11 +25,6 @@ impl Default for TabBundle {
         Self {
             tab: Default::default(),
             children: Default::default(),
-            styles: KStyle {
-                height: Units::Auto.into(),
-                top: Units::Pixels(0.0).into(),
-                ..Default::default()
-            },
             widget_name: Tab::default().get_name(),
         }
     }
@@ -51,7 +45,7 @@ pub fn tab_render(
             let styles = KStyle {
                 background_color: StyleProp::Value(Color::rgba(0.0781, 0.0898, 0.101, 1.0)),
                 padding: StyleProp::Value(Edge::all(Units::Pixels(15.0))),
-                height: Units::Pixels(100.0).into(),
+                height: Units::Stretch(1.0).into(),
                 width: Units::Stretch(1.0).into(),
                 ..Default::default()
             };
diff --git a/examples/tabs/tab_button.rs b/examples/tabs/tab_button.rs
index 1e10a418a96ef771c8fbe6ebfa19fbd0db96ab26..6099a8f2813e51907db0593c205ef26c8c04b048 100644
--- a/examples/tabs/tab_button.rs
+++ b/examples/tabs/tab_button.rs
@@ -1,9 +1,10 @@
 use bevy::prelude::{Bundle, Color, Commands, Component, Entity, In, Query};
-use kayak_ui::prelude::{
-    rsx,
-    widgets::{KButtonBundle, TextProps, TextWidgetBundle},
-    Event, EventDispatcherContext, EventType, KChildren, KStyle, KayakWidgetContext, OnEvent,
-    StyleProp, Units, Widget, WidgetName, WidgetState,
+use kayak_ui::{
+    prelude::{
+        rsx, widgets::KButtonBundle, Corner, Event, EventDispatcherContext, EventType, KStyle,
+        KayakWidgetContext, OnEvent, StyleProp, Units, Widget, WidgetName, WidgetState,
+    },
+    widgets::KButton,
 };
 
 use crate::tab_context::TabContext;
@@ -74,14 +75,18 @@ pub fn tab_button_render(
 
             rsx! {
                 <KButtonBundle
-                    on_event={on_event}
-                    styles={KStyle {
-                        background_color: StyleProp::Value(background_color),
-                        height: StyleProp::Value(Units::Pixels(25.0)),
+                    button={KButton {
+                        text: tab_button.title.clone(),
+                        user_styles: KStyle {
+                            background_color: StyleProp::Value(background_color),
+                            border_radius: Corner::all(0.0).into(),
+                            height: StyleProp::Value(Units::Pixels(25.0)),
+                            ..Default::default()
+                        },
                         ..Default::default()
-                    }}>
-                    <TextWidgetBundle text={TextProps { content: tab_button.title.clone(), size: 16.0, line_height: Some(16.0), ..Default::default() }} />
-                </KButtonBundle>
+                    }}
+                    on_event={on_event}
+                />
             }
         }
     }
diff --git a/examples/tabs/tabs.rs b/examples/tabs/tabs.rs
index 416f0a98b7fe934b102cbe988c0ab04518657d30..8df527c3ac4a7cb9f23ea5c882e1eea1de44bdcc 100644
--- a/examples/tabs/tabs.rs
+++ b/examples/tabs/tabs.rs
@@ -17,6 +17,9 @@ fn startup(
 ) {
     font_mapping.set_default(asset_server.load("roboto.kayak_font"));
 
+    // Camera 2D forces a clear pass in bevy.
+    // We do this because our scene is not rendering anything else.
+    commands.spawn(Camera2dBundle::default());
     commands.spawn(UICameraBundle::new());
 
     let mut widget_context = KayakRootContext::new();
@@ -89,6 +92,7 @@ fn startup(
 
 fn main() {
     App::new()
+        .insert_resource(ClearColor(Color::rgb(0.0, 0.0, 0.0)))
         .add_plugins(DefaultPlugins)
         .add_plugin(KayakContextPlugin)
         .add_plugin(KayakWidgets)
diff --git a/examples/text_box.rs b/examples/text_box.rs
index 723f96ef2f80bc03e43acd956a2e71cf7eb988e9..812b046fceb3287bd1f2a6cd8acdd05affe8f7f9 100644
--- a/examples/text_box.rs
+++ b/examples/text_box.rs
@@ -124,6 +124,7 @@ fn startup(
 
 fn main() {
     App::new()
+        .insert_resource(ClearColor(Color::rgb(0.0, 0.0, 0.0)))
         .add_plugins(DefaultPlugins)
         .add_plugin(KayakContextPlugin)
         .add_plugin(KayakWidgets)
diff --git a/examples/todo/input.rs b/examples/todo/input.rs
index 487632b62f3589c86d1b4c7e534b42db2641a3f5..6e6b15696afd3488aa053a7b385a9fd80546d688 100644
--- a/examples/todo/input.rs
+++ b/examples/todo/input.rs
@@ -4,9 +4,7 @@ use kayak_ui::prelude::{widgets::*, *};
 use crate::TodoList;
 
 #[derive(Component, Default, Clone, PartialEq)]
-pub struct TodoInputProps {
-    has_focus: bool,
-}
+pub struct TodoInputProps;
 
 impl Widget for TodoInputProps {}
 
@@ -39,120 +37,78 @@ impl Default for TodoInputBundle {
 pub fn render_todo_input(
     In((widget_context, entity)): In<(KayakWidgetContext, Entity)>,
     mut commands: Commands,
-    mut todo_list: ResMut<TodoList>,
-    keyboard_input: Res<Input<KeyCode>>,
-    change_query: Query<Entity, (With<TodoInputProps>, With<Mounted>)>,
-    prop_query: Query<&TodoInputProps>,
+    todo_list: Res<TodoList>,
 ) -> bool {
-    if todo_list.is_changed() || !change_query.is_empty() {
-        if let Ok(props) = prop_query.get(entity) {
-            let on_change = OnChange::new(
-                move |In((_widget_context, _, value)): In<(KayakWidgetContext, Entity, String)>,
-                      mut todo_list: ResMut<TodoList>| {
-                    todo_list.new_item = value;
-                },
-            );
+    let on_change = OnChange::new(
+        move |In((_widget_context, _, value)): In<(KayakWidgetContext, Entity, String)>,
+              mut todo_list: ResMut<TodoList>| {
+            todo_list.new_item = value;
+        },
+    );
 
-            if keyboard_input.just_pressed(KeyCode::Return) {
-                if props.has_focus {
-                    let value = todo_list.new_item.clone();
-                    todo_list.items.push(value);
-                    todo_list.new_item.clear();
+    let handle_click = OnEvent::new(
+        move |In((event_dispatcher_context, _, event, _)): In<(
+            EventDispatcherContext,
+            WidgetState,
+            Event,
+            Entity,
+        )>,
+              mut todo_list: ResMut<TodoList>| {
+            match event.event_type {
+                EventType::Click(..) => {
+                    if !todo_list.new_item.is_empty() {
+                        let value = todo_list.new_item.clone();
+                        todo_list.items.push(value);
+                        todo_list.new_item.clear();
+                    }
                 }
+                _ => {}
             }
+            (event_dispatcher_context, event)
+        },
+    );
 
-            let handle_click = OnEvent::new(
-                move |In((event_dispatcher_context, _, event, _)): In<(
-                    EventDispatcherContext,
-                    WidgetState,
-                    Event,
-                    Entity,
-                )>,
-                      mut todo_list: ResMut<TodoList>| {
-                    match event.event_type {
-                        EventType::Click(..) => {
-                            let value = todo_list.new_item.clone();
-                            todo_list.items.push(value);
-                            todo_list.new_item.clear();
-                        }
-                        _ => {}
-                    }
-                    (event_dispatcher_context, event)
-                },
-            );
-
-            let handle_focus = OnEvent::new(
-                move |In((event_dispatcher_context, _, event, _)): In<(
-                    EventDispatcherContext,
-                    WidgetState,
-                    Event,
-                    Entity,
-                )>,
-                      mut props_query: Query<&mut TodoInputProps>| {
-                    if let Ok(mut props) = props_query.get_mut(entity) {
-                        match event.event_type {
-                            EventType::Focus => {
-                                props.has_focus = true;
-                            }
-                            EventType::Blur => {
-                                props.has_focus = false;
-                            }
-                            _ => {}
-                        }
-                    }
-                    (event_dispatcher_context, event)
-                },
-            );
-
-            let parent_id = Some(entity);
-            rsx! {
-                <ElementBundle
-                    id={"element_bundle"}
-                    styles={KStyle {
-                        layout_type: StyleProp::Value(LayoutType::Row),
+    let parent_id = Some(entity);
+    rsx! {
+        <ElementBundle
+            id={"element_bundle"}
+            styles={KStyle {
+                layout_type: StyleProp::Value(LayoutType::Row),
+                height: StyleProp::Value(Units::Pixels(32.0)),
+                cursor: StyleProp::Value(KCursorIcon(CursorIcon::Text)),
+                ..Default::default()
+            }}
+        >
+            {
+                // You can spawn whatever you want on UI widgets this way! :)
+                commands.entity(element_bundle).insert(Focusable);
+            }
+            <TextBoxBundle
+                styles={KStyle {
+                    bottom: StyleProp::Value(Units::Stretch(1.0)),
+                    top: StyleProp::Value(Units::Stretch(1.0)),
+                    ..Default::default()
+                }}
+                text_box={TextBoxProps {
+                    value: todo_list.new_item.clone(),
+                    placeholder: Some("Add item here..".into()),
+                    ..Default::default()
+                }}
+                on_change={on_change}
+            />
+            <KButtonBundle
+                button={KButton {
+                    text: "+".into(),
+                    user_styles: KStyle {
+                        width: StyleProp::Value(Units::Pixels(32.0)),
                         height: StyleProp::Value(Units::Pixels(32.0)),
-                        cursor: StyleProp::Value(KCursorIcon(CursorIcon::Text)),
+                        left: StyleProp::Value(Units::Pixels(5.0)),
                         ..Default::default()
-                    }}
-                    on_event={handle_focus}
-                >
-                    {
-                        // You can spawn whatever you want on UI widgets this way! :)
-                        commands.entity(element_bundle).insert(Focusable);
                     }
-                    <TextBoxBundle
-                        styles={KStyle {
-                            bottom: StyleProp::Value(Units::Stretch(1.0)),
-                            top: StyleProp::Value(Units::Stretch(1.0)),
-                            ..Default::default()
-                        }}
-                        text_box={TextBoxProps {
-                            value: todo_list.new_item.clone(),
-                            placeholder: Some("Add item here..".into()),
-                            ..Default::default()
-                        }}
-                        on_change={on_change}
-                    />
-                    <KButtonBundle
-                        styles={KStyle {
-                            width: StyleProp::Value(Units::Pixels(32.0)),
-                            height: StyleProp::Value(Units::Pixels(32.0)),
-                            left: StyleProp::Value(Units::Pixels(5.0)),
-                            ..Default::default()
-                        }}
-                        on_event={handle_click}
-                    >
-                        <TextWidgetBundle
-                            text={TextProps {
-                                content: "+".into(),
-                                ..Default::default()
-                            }}
-                        />
-                    </KButtonBundle>
-                </ElementBundle>
-            }
-            return true;
-        }
+                }}
+                on_event={handle_click}
+            />
+        </ElementBundle>
     }
-    false
+    true
 }
diff --git a/examples/todo/items.rs b/examples/todo/items.rs
index 789589c306bbe73d8050815952f6ba7ec31d553c..2956999544d61f6734c5feba46eeb2416b0e052b 100644
--- a/examples/todo/items.rs
+++ b/examples/todo/items.rs
@@ -65,7 +65,7 @@ pub fn render_todo_items(
                     <ElementBundle
                         styles={KStyle {
                             render_command: StyleProp::Value(RenderCommand::Quad),
-                            background_color: StyleProp::Value(Color::rgba(0.0781, 0.0898, 0.101, 1.0)),
+                            background_color: Color::rgba(0.160, 0.172, 0.235, 1.0).into(),
                             border_radius: StyleProp::Value(Corner::all(3.0)),
                             bottom: StyleProp::Value(Units::Pixels(5.0)),
                             height: StyleProp::Value(Units::Auto),
@@ -77,29 +77,27 @@ pub fn render_todo_items(
                         <TextWidgetBundle
                             text={TextProps {
                                 content: content.clone(),
-                                ..Default::default()
-                            }}
-                            styles={KStyle {
-                                right: StyleProp::Value(Units::Stretch(1.0)),
-                                top: StyleProp::Value(Units::Stretch(1.0)),
-                                bottom: StyleProp::Value(Units::Stretch(1.0)),
+                                user_styles: KStyle {
+                                    right: StyleProp::Value(Units::Stretch(1.0)),
+                                    top: StyleProp::Value(Units::Stretch(1.0)),
+                                    bottom: StyleProp::Value(Units::Stretch(1.0)),
+                                    ..Default::default()
+                                },
                                 ..Default::default()
                             }}
                         />
                         <KButtonBundle
-                            styles={KStyle {
-                                width: StyleProp::Value(Units::Pixels(32.0)),
-                                height: StyleProp::Value(Units::Pixels(32.0)),
-                                left: StyleProp::Value(Units::Pixels(15.0)),
-                                ..Default::default()
+                            button={KButton {
+                                text: "X".into(),
+                                user_styles: KStyle {
+                                    width: StyleProp::Value(Units::Pixels(32.0)),
+                                    height: StyleProp::Value(Units::Pixels(32.0)),
+                                    left: StyleProp::Value(Units::Pixels(15.0)),
+                                    ..Default::default()
+                                }
                             }}
                             on_event={handle_click}
-                        >
-                            <TextWidgetBundle text={TextProps {
-                                content: "X".into(),
-                                ..Default::default()
-                            }} />
-                        </KButtonBundle>
+                        />
                     </ElementBundle>
                 }
             })}
diff --git a/examples/todo/todo.rs b/examples/todo/todo.rs
index 25481cf48f8c49a1b10d245e2334d0c2d55eb937..3da0b59182e5eb8b21505fd2e911b21189484bfc 100644
--- a/examples/todo/todo.rs
+++ b/examples/todo/todo.rs
@@ -48,6 +48,9 @@ fn startup(
 ) {
     font_mapping.set_default(asset_server.load("roboto.kayak_font"));
 
+    // Camera 2D forces a clear pass in bevy.
+    // We do this because our scene is not rendering anything else.
+    commands.spawn(Camera2dBundle::default());
     commands.spawn(UICameraBundle::new());
 
     let mut widget_context = KayakRootContext::new();
@@ -93,6 +96,7 @@ fn startup(
 
 fn main() {
     App::new()
+        .insert_resource(ClearColor(Color::rgb(0.0, 0.0, 0.0)))
         .add_plugins(DefaultPlugins)
         .add_plugin(KayakContextPlugin)
         .add_plugin(KayakWidgets)
diff --git a/kayak_ui_macros/src/widget.rs b/kayak_ui_macros/src/widget.rs
index 55f3ef489af03d2acf1faaf7d9d7755bc8b6592b..01f0b337f5d98e7edb2a7b3184eee0ff5fa073d0 100644
--- a/kayak_ui_macros/src/widget.rs
+++ b/kayak_ui_macros/src/widget.rs
@@ -73,6 +73,7 @@ impl Widget {
                     (
                         entity_id,
                         quote! {{
+                            let parent_org = parent_id;
                             #props
                             #widget_block
                         }},
@@ -197,14 +198,7 @@ impl Widget {
         }
 
         let props = quote! {
-            let entity = widget_context.get_child_at(parent_id);
-            let #entity_id = if let Some(entity) = entity {
-                // use bevy::prelude::DespawnRecursiveExt;
-                // commands.entity(entity).despawn_recursive();
-                commands.get_or_spawn(entity).id()
-            } else {
-                commands.spawn_empty().id()
-            };
+            let #entity_id = widget_context.spawn_widget(&mut commands, parent_org);
             let mut #prop_ident = #name {
                 #assigned_attrs
                 ..Default::default()
diff --git a/src/calculate_nodes.rs b/src/calculate_nodes.rs
index a053978ffb28298de8abe6d44943ef44084adbd7..4b7ccc82b76595ba3394e4894b0bab355e38ce9a 100644
--- a/src/calculate_nodes.rs
+++ b/src/calculate_nodes.rs
@@ -8,10 +8,10 @@ use morphorm::Hierarchy;
 use crate::{
     layout::{DataCache, Rect},
     node::{DirtyNode, Node, NodeBuilder, WrappedIndex},
-    prelude::{KStyle, KayakRootContext},
+    prelude::{KStyle, KayakRootContext, Tree},
     render::font::FontMapping,
     render_primitive::RenderPrimitive,
-    styles::{StyleProp, Units},
+    styles::{RenderCommand, StyleProp, Units},
 };
 
 pub fn calculate_nodes(
@@ -37,7 +37,11 @@ pub fn calculate_nodes(
     // if query.is_empty() {
     //     return;
     // }
-    if let Ok(tree) = context.tree.clone().read() {
+    if let Ok(tree) = context.tree.clone().try_read() {
+        if tree.root_node.is_none() {
+            return;
+        }
+
         for dirty_entity in query.iter() {
             let dirty_entity = WrappedIndex(dirty_entity);
             let styles = all_styles_query
@@ -48,10 +52,10 @@ pub fn calculate_nodes(
             // 2. Unresolved widget prop styles
             // 3. Unresolved default styles
             let parent_styles = if let Some(parent_widget_id) = tree.parents.get(&dirty_entity) {
-                if let Ok((_, parent_node)) = node_query.get(parent_widget_id.0) {
-                    parent_node.resolved_styles.clone()
-                } else if let Some(parent_node) = new_nodes.get(&parent_widget_id.0) {
+                if let Some(parent_node) = new_nodes.get(&parent_widget_id.0) {
                     parent_node.0.resolved_styles.clone()
+                } else if let Ok((_, parent_node)) = node_query.get(parent_widget_id.0) {
+                    parent_node.resolved_styles.clone()
                 } else if let Ok(parent_styles) = all_styles_query.get(parent_widget_id.0) {
                     parent_styles.clone()
                 } else {
@@ -61,27 +65,21 @@ pub fn calculate_nodes(
                 default_styles.clone()
             };
 
-            let parent_z = if let Some(parent_widget_id) = tree.parents.get(&dirty_entity) {
-                if let Ok((_, parent_node)) = node_query.get(parent_widget_id.0) {
-                    parent_node.z
-                } else if let Some(parent_node) = new_nodes.get(&parent_widget_id.0) {
-                    parent_node.0.z
-                } else {
-                    -1.0
-                }
-            } else {
-                -1.0
-            };
-
-            let current_z = {
-                if parent_z > -1.0 {
-                    parent_z + 1.0
-                } else {
-                    let z = context.current_z;
-                    context.current_z += 1.0;
-                    z
-                }
-            };
+            // let parent_z = if let Some(parent_widget_id) = tree.parents.get(&dirty_entity) {
+            //     if let Some(parent_node) = new_nodes.get(&parent_widget_id.0) {
+            //         parent_node.0.z
+            //     } else if let Ok((_, parent_node)) = node_query.get(parent_widget_id.0) {
+            //         parent_node.z
+            //     } else {
+            //         if let Ok(parent_styles) = all_styles_query.get(parent_widget_id.0) {
+            //             parent_styles.z_index.resolve() as f32
+            //         } else {
+            //             -1.0
+            //         }
+            //     }
+            // } else {
+            //     -1.0
+            // };
 
             let raw_styles = styles.clone();
             let mut styles = raw_styles.clone();
@@ -90,6 +88,22 @@ pub fn calculate_nodes(
             // Fill in all `inherited` values for any `inherit` property
             styles.inherit(&parent_styles);
 
+            // let mut current_z = {
+            //     if parent_z > -1.0 {
+            //         parent_z + 1.0
+            //     } else {
+            //         let z = context.current_z;
+            //         context.current_z += 1.0;
+            //         z
+            //     }
+            // };
+
+            let current_z = if matches!(styles.z_index, StyleProp::Value(..)) {
+                styles.z_index.resolve() as f32
+            } else {
+                -1.0
+            };
+
             let (primitive, needs_layout) = create_primitive(
                 &mut commands,
                 &context,
@@ -99,6 +113,11 @@ pub fn calculate_nodes(
                 // &node_query,
                 dirty_entity,
                 &mut styles,
+                node_query
+                    .get(dirty_entity.0)
+                    .and_then(|(_, node)| Ok(node.raw_styles.clone().unwrap_or_default()))
+                    .unwrap_or_default(),
+                &all_styles_query,
             );
 
             let children = tree.children.get(&dirty_entity).cloned().unwrap_or(vec![]);
@@ -127,6 +146,10 @@ pub fn calculate_nodes(
                     );
                 }
             }
+            node.old_z = node_query
+                .get(dirty_entity.0)
+                .and_then(|old_node| Ok(old_node.1.z))
+                .unwrap_or(0.0);
             node.z = current_z;
             new_nodes.insert(dirty_entity.0, (node, needs_layout));
         }
@@ -134,11 +157,13 @@ pub fn calculate_nodes(
         // let has_new_nodes = new_nodes.len() > 0;
 
         for (entity, (node, needs_layout)) in new_nodes.drain() {
-            commands.entity(entity).insert(node);
             if !needs_layout {
                 commands.entity(entity).remove::<DirtyNode>();
-                log::trace!("{:?} needs layout!", entity.id());
+            } else {
+                // log::info!("{:?} needs layout!", entity.id());
             }
+
+            commands.entity(entity).insert(node);
         }
     }
 }
@@ -162,7 +187,10 @@ pub fn calculate_layout(
             for (entity, change) in cache.geometry_changed.iter() {
                 if !change.is_empty() {
                     for child in tree.child_iter(*entity) {
-                        commands.entity(child.0).insert(DirtyNode);
+                        // log::info!("Layout changed for: {:?}", child.0.id());
+                        if let Some(mut entity_commands) = commands.get_entity(child.0) {
+                            entity_commands.insert(DirtyNode);
+                        }
                     }
                 }
             }
@@ -179,6 +207,8 @@ fn create_primitive(
     dirty: &Query<Entity, With<DirtyNode>>,
     id: WrappedIndex,
     styles: &mut KStyle,
+    prev_styles: KStyle,
+    all_styles_query: &Query<&KStyle>,
 ) -> (RenderPrimitive, bool) {
     let mut render_primitive = RenderPrimitive::from(&styles.clone());
     let mut needs_layout = true;
@@ -196,34 +226,64 @@ fn create_primitive(
             if let Some(font) = fonts.get(&font_handle) {
                 // self.bind(id, &asset);
                 if let Ok(node_tree) = context.tree.try_read() {
-                    if let Some(parent_id) = node_tree.get_parent(id) {
-                        if !dirty.contains(parent_id.0) {
-                            if let Some(parent_layout) = context.get_layout(&parent_id) {
-                                properties.max_size = (parent_layout.width, parent_layout.height);
-
-                                if properties.max_size.0 == 0.0 || properties.max_size.1 == 0.0 {
-                                    needs_layout = true;
-                                } else {
-                                    needs_layout = false;
-                                }
-
-                                if context.get_geometry_changed(&parent_id) {
-                                    needs_layout = true;
-                                }
-
-                                // --- Calculate Text Layout --- //
-                                *text_layout = font.measure(&content, *properties);
-                                let measurement = text_layout.size();
-
-                                // --- Apply Layout --- //
-                                if matches!(styles.width, StyleProp::Default) {
-                                    styles.width = StyleProp::Value(Units::Pixels(measurement.0));
-                                }
-                                if matches!(styles.height, StyleProp::Default) {
-                                    styles.height = StyleProp::Value(Units::Pixels(measurement.1));
-                                }
+                    if let Some(parent_id) =
+                        find_not_empty_parent(&node_tree, all_styles_query, &id)
+                    {
+                        if let Some(parent_layout) = context.get_layout(&parent_id) {
+                            let border_x = if let Ok(style) = all_styles_query.get(parent_id.0) {
+                                let border = style.border.resolve();
+                                border.left + border.right
+                            } else {
+                                0.0
+                            };
+                            let border_y = if let Ok(style) = all_styles_query.get(parent_id.0) {
+                                let border = style.border.resolve();
+                                border.top + border.bottom
+                            } else {
+                                0.0
+                            };
+                            properties.max_size = (
+                                parent_layout.width - border_x,
+                                parent_layout.height - border_y,
+                            );
+
+                            needs_layout = false;
+
+                            if properties.max_size.0 == 0.0 || properties.max_size.1 == 0.0 {
+                                needs_layout = true;
+                            }
+
+                            if context.get_geometry_changed(&parent_id) {
+                                needs_layout = true;
+                            }
+
+                            if dirty.contains(parent_id.0) {
+                                needs_layout = true;
+                            }
+
+                            // --- Calculate Text Layout --- //
+                            *text_layout = font.measure(&content, *properties);
+                            let measurement = text_layout.size();
+
+                            log::trace!(
+                                "Text Node: {}, has a measurement of: {:?}, it's parent takes up: {:?}",
+                                &content,
+                                measurement,
+                                properties.max_size
+                            );
+
+                            // --- Apply Layout --- //
+                            if matches!(styles.width, StyleProp::Default) {
+                                styles.width = StyleProp::Value(Units::Pixels(measurement.0));
+                            }
+                            if matches!(styles.height, StyleProp::Default) {
+                                styles.height = StyleProp::Value(Units::Pixels(measurement.1));
                             }
+                        } else {
+                            log::trace!("no layout for: {:?}", parent_id.0.id());
                         }
+                    } else {
+                        log::trace!("No parent found for: {:?}", id.0.id());
                     }
                 }
             }
@@ -237,9 +297,38 @@ fn create_primitive(
         commands.entity(id.0).insert(DirtyNode);
     }
 
+    // If we have data from the previous frame no need to do anything here!
+    if matches!(prev_styles.width, StyleProp::Value(..)) {
+        styles.width = prev_styles.width;
+        styles.height = prev_styles.height;
+        needs_layout = false;
+    }
+
     (render_primitive, needs_layout)
 }
 
+pub fn find_not_empty_parent(
+    tree: &Tree,
+    all_styles_query: &Query<&KStyle>,
+    node: &WrappedIndex,
+) -> Option<WrappedIndex> {
+    if let Some(parent) = tree.parent(*node) {
+        if let Ok(styles) = all_styles_query.get(parent.0) {
+            if matches!(styles.render_command.resolve(), RenderCommand::Empty)
+                || matches!(styles.render_command.resolve(), RenderCommand::Layout)
+            {
+                find_not_empty_parent(tree, all_styles_query, &parent)
+            } else {
+                Some(parent)
+            }
+        } else {
+            find_not_empty_parent(tree, all_styles_query, &parent)
+        }
+    } else {
+        None
+    }
+}
+
 // pub fn build_nodes_tree(context: &mut Context, tree: &Tree, node_query: &Query<(Entity, &Node)>) {
 //     if tree.root_node.is_none() {
 //         return;
diff --git a/src/children.rs b/src/children.rs
index 810be98b807207929765b14109c9687f04edd810..10546b2baaac5d9acbf0f38bef975c8e716c4a04 100644
--- a/src/children.rs
+++ b/src/children.rs
@@ -30,6 +30,14 @@ impl KChildren {
         }
     }
 
+    pub fn iter(&self) -> std::slice::Iter<Entity> {
+        self.inner.iter()
+    }
+
+    pub fn len(&self) -> usize {
+        self.inner.len()
+    }
+
     pub fn despawn(&mut self, commands: &mut Commands) {
         for child in self.inner.drain(..) {
             commands.entity(child).despawn_recursive();
diff --git a/src/clone_component.rs b/src/clone_component.rs
index 5cfb47b9e946d3c78cbaca206be7638bcd0229e5..151410986845422b26deba5ca54810e3b90c16bb 100644
--- a/src/clone_component.rs
+++ b/src/clone_component.rs
@@ -20,7 +20,9 @@ pub(crate) fn clone_system<T: Clone + Component>(
 ) {
     if let Some(v) = world.entity(reference).get::<T>() {
         let v = v.clone();
-        world.entity_mut(target).insert(v);
+        if let Some(mut entity) = world.get_entity_mut(target) {
+            entity.insert(v);
+        }
     }
 }
 
diff --git a/src/context.rs b/src/context.rs
index 85c4c85dedc42b96a25cae3336a67a1c92ac63d3..777cd360bd896da5475946946051f1cfe0b173ee 100644
--- a/src/context.rs
+++ b/src/context.rs
@@ -81,7 +81,8 @@ pub struct KayakRootContext {
     pub(crate) clone_systems: Arc<RwLock<EntityCloneSystems>>,
     pub(crate) cloned_widget_entities: Arc<RwLock<HashMap<Entity, Entity>>>,
     pub(crate) widget_state: WidgetState,
-    index: Arc<RwLock<HashMap<Entity, usize>>>,
+    pub(crate) order_tree: Arc<RwLock<Tree>>,
+    pub(crate) index: Arc<RwLock<HashMap<Entity, usize>>>,
 }
 
 impl KayakRootContext {
@@ -99,6 +100,7 @@ impl KayakRootContext {
             cloned_widget_entities: Default::default(),
             widget_state: Default::default(),
             index: Default::default(),
+            order_tree: Default::default(),
         }
     }
 
@@ -188,36 +190,58 @@ impl KayakRootContext {
         }
     }
 
-    /// Returns a child entity or none if it does not exist.
+    /// Returns a new/existing widget entity.
     /// Because a re-render can potentially spawn new entities it's advised to use this
     /// to avoid creating a new entity.
     ///
     /// Usage:
+    /// ```rust
     /// fn setup() {
     ///     let mut widget_context = WidgetContext::new();
     ///     // Root tree node, no parent node.
-    ///     let root_entity = if let Some(root_entity) =  widget_context.get_child_at(None) {\
-    ///         root_entity
-    ///     } else {
-    ///         // Spawn if it does not exist in the tree!
-    ///         commands.spawn_empty().id()
-    ///     };
+    ///     let root_entity =  widget_context.spawn_widget(&mut commands, None);
     ///     commands.entity(root_entity).insert(KayakAppBundle::default());
     ///     widget_context.add_widget(None, root_entity);
     /// }
-    ///
-    ///
-    pub fn get_child_at(&self, parent_entity: Option<Entity>) -> Option<Entity> {
-        if let Ok(tree) = self.tree.try_read() {
-            if let Some(entity) = parent_entity {
-                let children = tree.child_iter(WrappedIndex(entity)).collect::<Vec<_>>();
-                return children
-                    .get(self.get_and_add_index(entity))
-                    .cloned()
-                    .map(|index| index.0);
+    ///```
+    pub fn spawn_widget(&self, commands: &mut Commands, parent_id: Option<Entity>) -> Entity {
+        let mut entity = None;
+        if let Some(parent_entity) = parent_id {
+            let children = self.get_children_ordered(parent_entity);
+            let child = children.get(self.get_and_add_index(parent_entity)).cloned();
+            if let Some(child) = child {
+                log::trace!("Reusing widget entity {:?}!", child.id());
+                entity = Some(commands.get_or_spawn(child).id());
             }
         }
-        None
+
+        // If we have no entity spawn it!
+        if entity.is_none() {
+            entity = Some(commands.spawn_empty().id());
+            log::trace!(
+                "Spawning new widget with entity {:?}!",
+                entity.unwrap().id()
+            );
+            // We need to add it to the ordered tree
+            if let Ok(mut tree) = self.order_tree.try_write() {
+                tree.add(
+                    WrappedIndex(entity.unwrap()),
+                    parent_id.and_then(|parent| Some(WrappedIndex(parent))),
+                )
+            }
+        }
+        entity.unwrap()
+    }
+
+    fn get_children_ordered(&self, entity: Entity) -> Vec<Entity> {
+        let mut children = vec![];
+        if let Ok(tree) = self.order_tree.read() {
+            let iterator = tree.child_iter(WrappedIndex(entity));
+
+            children = iterator.map(|index| index.0).collect::<Vec<_>>();
+        }
+
+        children
     }
 
     fn get_and_add_index(&self, parent: Entity) -> usize {
@@ -256,98 +280,139 @@ impl KayakRootContext {
 
         // self.node_tree.dump();
 
-        recurse_node_tree_to_build_primitives(
-            &*node_tree,
-            &self.layout_cache,
-            nodes,
-            widget_names,
-            node_tree.root_node.unwrap(),
-            0.0,
-            RenderPrimitive::Empty,
-        )
+        let render_primitives = if let Ok(mut layout_cache) = self.layout_cache.try_write() {
+            recurse_node_tree_to_build_primitives(
+                &*node_tree,
+                &mut layout_cache,
+                nodes,
+                widget_names,
+                node_tree.root_node.unwrap(),
+                0.0,
+                RenderPrimitive::Empty,
+            )
+        } else {
+            vec![]
+        };
+        // render_primitives.sort_by(|a, b| a.0.partial_cmp(&b.0).unwrap());
+
+        // render_primitives.iter().enumerate().for_each(|(index, p)| {
+        //     log::info!("Name: {:?}, Z: {:?}", p.to_string(), index);
+        // });
+
+        // dbg!(&render_primitives
+        //     .iter()
+        //     .map(|a| (a.1.to_string(), a.0))
+        //     .collect::<Vec<_>>());
+
+        render_primitives.into_iter().collect()
     }
 }
 
 fn recurse_node_tree_to_build_primitives(
     node_tree: &Tree,
-    layout_cache: &Arc<RwLock<LayoutCache>>,
+    layout_cache: &mut LayoutCache,
     nodes: &Query<&crate::node::Node>,
     widget_names: &Query<&WidgetName>,
     current_node: WrappedIndex,
-    mut main_z_index: f32,
+    main_z_index: f32,
     mut prev_clip: RenderPrimitive,
 ) -> Vec<RenderPrimitive> {
     let mut render_primitives = Vec::new();
     if let Ok(node) = nodes.get(current_node.0) {
-        if let Ok(cache) = layout_cache.try_read() {
-            if let Some(layout) = cache.rect.get(&current_node) {
-                let mut render_primitive = node.primitive.clone();
-                let mut layout = *layout;
-                let new_z_index = if matches!(render_primitive, RenderPrimitive::Clip { .. }) {
-                    main_z_index - 0.1
-                } else {
-                    main_z_index
-                };
-                layout.z_index = new_z_index;
-                render_primitive.set_layout(layout);
-
-                if matches!(render_primitive, RenderPrimitive::Empty) {
-                    log::trace!(
-                        "No render primitive for node: {}-{}",
-                        widget_names.get(current_node.0).unwrap().0,
-                        current_node.0.id(),
-                    );
-                }
+        let mut render_primitive = node.primitive.clone();
+        let mut new_z_index = if matches!(render_primitive, RenderPrimitive::Clip { .. }) {
+            main_z_index
+        } else {
+            main_z_index
+        };
+        let _layout = if let Some(layout) = layout_cache.rect.get_mut(&current_node) {
+            // log::info!(
+            //     "z_index is {} and node.z is {} for: {}-{}",
+            //     new_z_index,
+            //     node.z,
+            //     widget_names.get(current_node.0).unwrap().0,
+            //     current_node.0.id(),
+            // );
+
+            new_z_index += if node.z <= 0.0 { 0.0 } else { node.z };
+
+            layout.z_index = new_z_index;
+            render_primitive.set_layout(*layout);
+            *layout
+        } else {
+            log::warn!(
+                "No layout for node: {}-{}",
+                widget_names.get(current_node.0).unwrap().0,
+                current_node.0.id()
+            );
+            Rect::default()
+        };
 
-                render_primitives.push(render_primitive.clone());
+        match &render_primitive {
+            RenderPrimitive::Text { content, .. } => {
+                log::trace!(
+                    "Text node: {}-{} is equal to: {}",
+                    widget_names.get(current_node.0).unwrap().0,
+                    current_node.0.id(),
+                    content,
+                );
+            }
+            RenderPrimitive::Empty => {
+                log::trace!(
+                    "Empty node: {}-{}",
+                    widget_names.get(current_node.0).unwrap().0,
+                    current_node.0.id(),
+                );
+            }
+            _ => {}
+        }
 
-                let new_prev_clip = if matches!(render_primitive, RenderPrimitive::Clip { .. }) {
-                    render_primitive.clone()
-                } else {
-                    prev_clip
-                };
+        render_primitives.push(render_primitive.clone());
 
-                prev_clip = new_prev_clip.clone();
-                if node_tree.children.contains_key(&current_node) {
-                    for child in node_tree.children.get(&current_node).unwrap() {
-                        main_z_index += 1.0;
-                        render_primitives.extend(recurse_node_tree_to_build_primitives(
-                            node_tree,
-                            layout_cache,
-                            nodes,
-                            widget_names,
-                            *child,
-                            main_z_index,
-                            new_prev_clip.clone(),
-                        ));
-
-                        main_z_index = layout.z_index;
-                        // Between each child node we need to reset the clip.
-                        if matches!(prev_clip, RenderPrimitive::Clip { .. }) {
-                            // main_z_index = new_z_index;
-                            match &mut prev_clip {
-                                RenderPrimitive::Clip { layout } => {
-                                    layout.z_index = main_z_index + 0.1;
-                                }
-                                _ => {}
-                            };
-                            render_primitives.push(prev_clip.clone());
-                        }
-                    }
-                } else {
-                    log::trace!(
-                        "No children for node: {}-{}",
-                        widget_names.get(current_node.0).unwrap().0,
-                        current_node.0.id()
-                    );
-                }
-            } else {
-                log::warn!(
-                    "No layout for node: {}-{}",
-                    widget_names.get(current_node.0).unwrap().0,
-                    current_node.0.id()
+        let new_prev_clip = if matches!(render_primitive, RenderPrimitive::Clip { .. }) {
+            render_primitive.clone()
+        } else {
+            prev_clip
+        };
+
+        prev_clip = new_prev_clip.clone();
+        if node_tree.children.contains_key(&current_node) {
+            let z = 1.0f32;
+            let mut children_primitives = Vec::new();
+            for child in node_tree.children.get(&current_node).unwrap() {
+                // main_z_index += 1.0;
+                let mut children_p = recurse_node_tree_to_build_primitives(
+                    node_tree,
+                    layout_cache,
+                    nodes,
+                    widget_names,
+                    *child,
+                    main_z_index + if node.z < 0.0 { 0.0 } else { node.z } + z,
+                    new_prev_clip.clone(),
                 );
+
+                // Between each child node we need to reset the clip.
+                if matches!(prev_clip, RenderPrimitive::Clip { .. }) {
+                    children_p.push(prev_clip.clone());
+                }
+
+                if let Ok(node) = nodes.get(child.0) {
+                    let zz = if node.z < 0.0 { z } else { z + node.z };
+                    children_primitives.push((zz, children_p));
+                }
             }
+
+            // Sort and add
+            children_primitives.sort_by(|a, b| a.0.partial_cmp(&b.0).unwrap());
+            for cp in children_primitives.drain(..) {
+                render_primitives.extend(cp.1);
+            }
+        } else {
+            log::trace!(
+                "No children for node: {}-{}",
+                widget_names.get(current_node.0).unwrap().0,
+                current_node.0.id()
+            );
         }
     } else {
         log::error!(
@@ -365,7 +430,10 @@ fn recurse_node_tree_to_build_primitives(
                 )
                 .and_then(|v| Ok(v.0.clone()))
                 .unwrap_or("None".into()),
-            widget_names.get(current_node.0).unwrap().0,
+            widget_names
+                .get(current_node.0)
+                .and_then(|v| Ok(v.0.clone()))
+                .unwrap_or("None".into()),
             current_node.0.id()
         );
     }
@@ -411,6 +479,8 @@ fn update_widgets_sys(world: &mut World) {
         &context.cloned_widget_entities,
         &context.widget_state,
         &mut new_ticks,
+        &context.order_tree,
+        &context.index,
     );
 
     if let Some(old_focus) = old_focus {
@@ -435,8 +505,18 @@ fn update_widgets_sys(world: &mut World) {
         // system.apply_buffers(world);
     }
 
-    // if let Ok(tree) = context.tree.try_read() {
-    // tree.dump();
+    // Clear out indices
+    if let Ok(mut indices) = context.index.try_write() {
+        // for (entity, value) in indices.iter_mut() {
+        //     if tree.root_node.unwrap().0.id() != entity.id() {
+        //         *value = 0;
+        //     }
+        // }
+        indices.clear();
+    }
+
+    // if let Ok(order_tree) = context.order_tree.try_read() {
+    //     order_tree.dump();
     // }
 
     world.insert_resource(context);
@@ -454,6 +534,8 @@ fn update_widgets(
     cloned_widget_entities: &Arc<RwLock<HashMap<Entity, Entity>>>,
     widget_state: &WidgetState,
     new_ticks: &mut HashMap<String, u32>,
+    order_tree: &Arc<RwLock<Tree>>,
+    index: &Arc<RwLock<HashMap<Entity, usize>>>,
 ) {
     for entity in widgets.iter() {
         if let Some(entity_ref) = world.get_entity(entity.0) {
@@ -463,9 +545,12 @@ fn update_widgets(
                     context_entities.clone(),
                     layout_cache.clone(),
                     widget_state.clone(),
+                    order_tree.clone(),
+                    index.clone(),
                 );
                 widget_context.copy_from_point(&tree, *entity);
                 let children_before = widget_context.get_children(entity.0);
+                let widget_name = widget_type.0.clone();
                 let (widget_context, should_update_children) = update_widget(
                     systems,
                     tree,
@@ -482,27 +567,82 @@ fn update_widgets(
 
                 if should_update_children {
                     if let Ok(mut tree) = tree.write() {
+                        // let mut had_removal = false;
                         let diff = tree.diff_children(&widget_context, *entity, UPDATE_DEPTH);
                         for (_index, child, _parent, changes) in diff.changes.iter() {
-                            for change in changes.iter() {
-                                if matches!(change, Change::Inserted) {
-                                    if let Ok(mut cache) = layout_cache.try_write() {
-                                        cache.add(*child);
+                            if changes
+                                .iter()
+                                .any(|change| matches!(change, Change::Inserted))
+                            {
+                                if let Ok(mut cache) = layout_cache.try_write() {
+                                    cache.add(*child);
+                                }
+                            }
+
+                            if changes
+                                .iter()
+                                .any(|change| matches!(change, Change::Deleted))
+                            {
+                                // Children of this node need to be despawned.
+                                let mut despawn_list = Vec::default();
+                                for child in tree.down_iter_at(*child, true) {
+                                    let children = if let Some(parent) = tree.get_parent(child) {
+                                        world.entity(parent.0).get::<KChildren>()
+                                    } else {
+                                        None
+                                    };
+
+                                    if let Some(children) = children {
+                                        if !children.iter().any(|c| *c == child.0) {
+                                            despawn_list.push(child.0);
+                                        }
+                                    } else {
+                                        despawn_list.push(child.0);
+                                    }
+                                    if let Ok(mut order_tree) = order_tree.try_write() {
+                                        // had_removal = true;
+                                        log::trace!(
+                                            "Removing entity! {:?} inside of: {}-{:?}",
+                                            child.0.id(),
+                                            widget_name,
+                                            entity.0.id()
+                                        );
+                                        order_tree.remove(child);
+                                    }
+                                }
+                                for entity in despawn_list.drain(..) {
+                                    if let Some(entity_mut) = world.get_entity_mut(entity) {
+                                        entity_mut.despawn();
                                     }
                                 }
                             }
                         }
-                        // dbg!("Dumping widget tree:");
-                        // widget_context.dump_at(*entity);
-                        // dbg!(entity.0, &diff);
+
+                        // if had_removal {
+                        //     tree.dump();
+                        //     dbg!(&diff);
+                        // }
 
                         tree.merge(&widget_context, *entity, diff, UPDATE_DEPTH);
-                        // dbg!(tree.dump_at(*entity));
+
+                        // if had_removal {
+                        //     tree.dump();
+                        // }
+
+                        for child in widget_context.child_iter(*entity) {
+                            if let Some(mut entity_commands) = world.get_entity_mut(child.0) {
+                                entity_commands.insert(DirtyNode);
+                            }
+                        }
                     }
                 }
 
                 // if should_update_children {
-                let children = widget_context.child_iter(*entity).collect::<Vec<_>>();
+                let children = if let Ok(tree) = tree.read() {
+                    tree.child_iter(*entity).collect::<Vec<_>>()
+                } else {
+                    vec![]
+                };
                 update_widgets(
                     world,
                     tree,
@@ -515,6 +655,8 @@ fn update_widgets(
                     cloned_widget_entities,
                     widget_state,
                     new_ticks,
+                    order_tree,
+                    index,
                 );
                 // }
             }
@@ -550,8 +692,16 @@ fn update_widget(
     let should_rerender = {
         let old_props_entity =
             if let Ok(mut cloned_widget_entities) = cloned_widget_entities.try_write() {
-                if let Some(entity) = cloned_widget_entities.get(&entity.0) {
-                    *entity
+                if let Some(entity) = cloned_widget_entities.get(&entity.0).cloned() {
+                    if let Some(possible_entity) = world.get_entity(entity) {
+                        let target = possible_entity.id();
+                        cloned_widget_entities.insert(entity, target);
+                        target
+                    } else {
+                        let target = world.spawn_empty().insert(PreviousWidget).id();
+                        cloned_widget_entities.insert(entity, target);
+                        target
+                    }
                 } else {
                     let target = world.spawn_empty().insert(PreviousWidget).id();
                     cloned_widget_entities.insert(entity.0, target);
@@ -571,16 +721,23 @@ fn update_widget(
 
         if should_rerender {
             if let Ok(cloned_widget_entities) = cloned_widget_entities.try_read() {
-                let target_entity = cloned_widget_entities.get(&entity.0).unwrap();
-                if let Ok(clone_systems) = clone_systems.try_read() {
-                    for s in clone_systems.0.iter() {
-                        s.0(world, *target_entity, entity.0);
-                        s.1(world, *target_entity, entity.0, &widget_state);
-                        if let Some(styles) = world.entity(entity.0).get::<KStyle>().cloned() {
-                            world.entity_mut(*target_entity).insert(styles);
-                        }
-                        if let Some(children) = world.entity(entity.0).get::<KChildren>().cloned() {
-                            world.entity_mut(*target_entity).insert(children);
+                if let Some(target_entity) = cloned_widget_entities.get(&entity.0) {
+                    if let Ok(clone_systems) = clone_systems.try_read() {
+                        for s in clone_systems.0.iter() {
+                            s.0(world, *target_entity, entity.0);
+                            s.1(world, *target_entity, entity.0, &widget_state);
+                            if let Some(styles) = world.entity(entity.0).get::<KStyle>().cloned() {
+                                if let Some(mut entity) = world.get_entity_mut(*target_entity) {
+                                    entity.insert(styles);
+                                }
+                            }
+                            if let Some(children) =
+                                world.entity(entity.0).get::<KChildren>().cloned()
+                            {
+                                if let Some(mut entity) = world.get_entity_mut(*target_entity) {
+                                    entity.insert(children);
+                                }
+                            }
                         }
                     }
                 }
@@ -600,8 +757,31 @@ fn update_widget(
     // }
 
     let should_update_children;
-    log::trace!("Re-rendering: {:?} {:?}", &widget_type, entity.0.id());
+    if let Ok(tree) = tree.try_read() {
+        log::trace!(
+            "Re-rendering: {:?} {:?}, parent: {:?}",
+            &widget_type,
+            entity.0.id(),
+            tree.parent(entity)
+                .unwrap_or(WrappedIndex(Entity::from_raw(99999)))
+                .0
+                .id()
+        );
+    }
     {
+        // Before rendering widget we need to advance the indices correctly..
+        if let Some(children) = world.get::<KChildren>(entity.0) {
+            let child_count = children.len();
+            if let Ok(mut indices) = widget_context.index.try_write() {
+                indices.insert(entity.0, 0);
+                log::trace!(
+                    "Advancing children for: {:?} by: {:?}",
+                    entity.0.id(),
+                    child_count
+                );
+            }
+        }
+
         // Remove children from previous render.
         widget_context.remove_children(previous_children);
         let widget_render_system = &mut systems.get_mut(&widget_type).unwrap().1;
@@ -612,6 +792,10 @@ fn update_widget(
         new_ticks.insert(widget_type.clone(), new_tick);
         widget_render_system.set_last_change_tick(old_tick);
         widget_render_system.apply_buffers(world);
+
+        if let Ok(mut indices) = widget_context.index.try_write() {
+            indices.insert(entity.0, 0);
+        }
     }
     let widget_context = widget_context.take();
     let mut command_queue = CommandQueue::default();
@@ -631,34 +815,36 @@ fn update_widget(
     // Mark node as needing a recalculation of rendering/layout.
     commands.entity(entity.0).insert(DirtyNode);
 
-    for child in widget_context.child_iter(entity) {
-        commands.entity(child.0).insert(DirtyNode);
-    }
-
-    if let Ok(cloned_widget_entities) = cloned_widget_entities.try_read() {
-        let target_entity = cloned_widget_entities.get(&entity.0).unwrap();
-        if let Some(styles) = world.entity(entity.0).get::<KStyle>().cloned() {
-            commands.entity(*target_entity).insert(styles);
-        }
-        if let Some(children) = world.entity(entity.0).get::<KChildren>().cloned() {
-            commands.entity(*target_entity).insert(children);
+    for (_index, changed_entity, _parent, changes) in diff.changes.iter() {
+        if changes.iter().any(|change| *change == Change::Deleted) {
+            // commands.entity(changed_entity.0).despawn();
+            // commands.entity(changed_entity.0).remove::<DirtyNode>();
+            // commands.entity(changed_entity.0).despawn_recursive();
         }
-    }
-
-    if should_update_children {
-        for (_, changed_entity, _, changes) in diff.changes.iter() {
-            if changes.iter().any(|change| *change == Change::Deleted) {
-                // commands.entity(changed_entity.0).despawn();
-                commands.entity(changed_entity.0).remove::<DirtyNode>();
-            }
-            if changes.iter().any(|change| *change == Change::Inserted) {
-                commands.entity(changed_entity.0).insert(Mounted);
+        if changes.iter().any(|change| *change == Change::Inserted) {
+            if let Some(mut entity_commands) = commands.get_entity(changed_entity.0) {
+                entity_commands.insert(Mounted);
             }
         }
     }
+
     command_queue.apply(world);
 
     if should_update_children {
+        if let Ok(cloned_widget_entities) = cloned_widget_entities.try_read() {
+            if let Some(target_entity) = cloned_widget_entities.get(&entity.0) {
+                if let Some(styles) = world.entity(entity.0).get::<KStyle>().cloned() {
+                    if let Some(mut entity) = world.get_entity_mut(*target_entity) {
+                        entity.insert(styles);
+                    }
+                }
+                if let Some(children) = world.entity(entity.0).get::<KChildren>().cloned() {
+                    if let Some(mut entity) = world.get_entity_mut(*target_entity) {
+                        entity.insert(children);
+                    }
+                }
+            }
+        }
         for (_, child_entity, _, changes) in diff.changes.iter() {
             // Clone to entity.
             if changes.iter().any(|change| *change == Change::Deleted) {
@@ -729,7 +915,7 @@ fn calculate_ui(world: &mut World) {
     let mut layout_system = IntoSystem::into_system(calculate_layout);
     layout_system.initialize(world);
 
-    for _ in 0..5 {
+    for _ in 0..3 {
         node_system.run((), world);
         node_system.apply_buffers(world);
 
@@ -771,7 +957,7 @@ fn calculate_ui(world: &mut World) {
 
 /// A simple component that stores the type name of a widget
 /// This is used by Kayak in order to find out which systems to run.
-#[derive(Component, Debug)]
+#[derive(Component, Debug, Clone, PartialEq)]
 pub struct WidgetName(pub String);
 
 impl From<String> for WidgetName {
diff --git a/src/event.rs b/src/event.rs
index 7442a2382ddb9a8dc63d5eb78376bd7c0eefbcfa..773a89fd2dbbbab4818909bbbe176d58fe082ecf 100644
--- a/src/event.rs
+++ b/src/event.rs
@@ -21,6 +21,8 @@ pub struct Event {
     pub(crate) default_prevented: bool,
     /// OnChange systems to call afterwards
     pub(crate) on_change_systems: Vec<OnChange>,
+
+    pub testing_z_index: f32,
 }
 
 impl Default for Event {
@@ -32,6 +34,7 @@ impl Default for Event {
             should_propagate: true,
             default_prevented: false,
             on_change_systems: Vec::new(),
+            testing_z_index: 0.0,
         }
     }
 }
@@ -49,6 +52,7 @@ impl Event {
             should_propagate: event_type.propagates(),
             default_prevented: false,
             on_change_systems: Vec::new(),
+            testing_z_index: 0.0,
         }
     }
 
@@ -59,7 +63,17 @@ impl Event {
 
     /// If called, prevents this event from propagating up the hierarchy
     pub fn stop_propagation(&mut self) {
-        self.should_propagate = false;
+        if matches!(
+            self.event_type,
+            EventType::Click(..)
+                | EventType::MouseIn(..)
+                | EventType::MouseDown(..)
+                | EventType::Scroll(..)
+                | EventType::Focus
+                | EventType::Hover(..)
+        ) {
+            self.should_propagate = false;
+        }
     }
 
     /// Returns whether this event's default action has been prevented or not
diff --git a/src/event_dispatcher.rs b/src/event_dispatcher.rs
index 53a6340bd5c337afac1fce29181221593e1a87de..3c80a66e601bb6d358e725e5d9568af6ae8a0382 100644
--- a/src/event_dispatcher.rs
+++ b/src/event_dispatcher.rs
@@ -11,7 +11,7 @@ use crate::{
     input_event::{InputEvent, InputEventCategory},
     keyboard_event::{KeyboardEvent, KeyboardModifiers},
     layout::Rect,
-    node::WrappedIndex,
+    node::{Node, WrappedIndex},
     on_event::OnEvent,
     prelude::KayakWidgetContext,
     styles::{KStyle, RenderCommand},
@@ -243,6 +243,8 @@ impl EventDispatcher {
                             context.context_entities.clone(),
                             context.layout_cache.clone(),
                             context.widget_state.clone(),
+                            context.order_tree.clone(),
+                            context.index.clone(),
                         );
                         node_event.run_on_change(world, widget_context);
                     }
@@ -382,30 +384,32 @@ impl EventDispatcher {
                     let (current, depth) = stack.pop().unwrap();
                     let mut enter_children = true;
 
-                    for input_event in input_events {
-                        // --- Process Event --- //
-                        if matches!(input_event.category(), InputEventCategory::Mouse) {
-                            // A widget's PointerEvents style will determine how it and its children are processed
-                            let pointer_events = Self::resolve_pointer_events(current, world);
-
-                            match pointer_events {
-                                PointerEvents::All | PointerEvents::SelfOnly => {
-                                    let events = self.process_pointer_events(
-                                        input_event,
-                                        (current, depth),
-                                        &mut states,
-                                        world,
-                                        context,
-                                        false,
-                                    );
-                                    event_stream.extend(events);
-
-                                    if matches!(pointer_events, PointerEvents::SelfOnly) {
-                                        enter_children = false;
+                    if world.entity(current.0).contains::<OnEvent>() {
+                        for input_event in input_events {
+                            // --- Process Event --- //
+                            if matches!(input_event.category(), InputEventCategory::Mouse) {
+                                // A widget's PointerEvents style will determine how it and its children are processed
+                                let pointer_events = Self::resolve_pointer_events(current, world);
+
+                                match pointer_events {
+                                    PointerEvents::All | PointerEvents::SelfOnly => {
+                                        let events = self.process_pointer_events(
+                                            input_event,
+                                            (current, depth),
+                                            &mut states,
+                                            world,
+                                            context,
+                                            false,
+                                        );
+                                        event_stream.extend(events);
+
+                                        if matches!(pointer_events, PointerEvents::SelfOnly) {
+                                            enter_children = false;
+                                        }
                                     }
+                                    PointerEvents::None => enter_children = false,
+                                    PointerEvents::ChildrenOnly => {}
                                 }
-                                PointerEvents::None => enter_children = false,
-                                PointerEvents::ChildrenOnly => {}
                             }
                         }
                     }
@@ -413,9 +417,17 @@ impl EventDispatcher {
                     // --- Push Children to Stack --- //
                     if enter_children {
                         if let Some(children) = node_tree.children.get(&current) {
+                            let mut stack_children = Vec::new();
                             for child in children {
-                                stack.push((*child, depth + 1));
+                                let child_z = world
+                                    .entity(child.0)
+                                    .get::<Node>()
+                                    .and_then(|node| Some(node.z))
+                                    .unwrap_or(0.0);
+                                stack_children.push((child_z, (*child, depth + 1)));
                             }
+                            stack_children.sort_by(|a, b| a.0.partial_cmp(&b.0).unwrap());
+                            stack.extend(stack_children.iter().map(|c| c.1));
                         }
                     }
                 }
@@ -511,6 +523,9 @@ impl EventDispatcher {
         let mut event_stream = Vec::<Event>::new();
         let (node, depth) = tree_node;
 
+        // let widget_name = world.entity(node.0).get::<WidgetName>();
+        // dbg!(widget_name);
+
         match input_event {
             InputEvent::MouseMoved(point) => {
                 if let Some(layout) = context.get_layout(&node) {
@@ -519,10 +534,23 @@ impl EventDispatcher {
                     let is_contained = layout.contains(point);
                     if !ignore_layout && was_contained != is_contained {
                         if was_contained {
+                            // Mouse out should fire even when
                             event_stream
                                 .push(Event::new(node.0, EventType::MouseOut(cursor_event)));
+                            // Self::update_state(
+                            //     states,
+                            //     (node, depth),
+                            //     &layout,
+                            //     EventType::MouseOut(cursor_event),
+                            // );
                         } else {
-                            event_stream.push(Event::new(node.0, EventType::MouseIn(cursor_event)));
+                            // event_stream.push(Event::new(node.0, EventType::MouseIn(cursor_event)));
+                            Self::update_state(
+                                states,
+                                (node, depth),
+                                &layout,
+                                EventType::MouseIn(cursor_event),
+                            );
                         }
                     }
                     if self.contains_cursor.is_none() || !self.contains_cursor.unwrap_or_default() {
@@ -557,7 +585,13 @@ impl EventDispatcher {
                 if let Some(layout) = context.get_layout(&node) {
                     if ignore_layout || layout.contains(&self.current_mouse_position) {
                         let cursor_event = self.get_cursor_event(self.current_mouse_position);
-                        event_stream.push(Event::new(node.0, EventType::MouseDown(cursor_event)));
+                        // event_stream.push(Event::new(node.0, EventType::MouseDown(cursor_event)));
+                        Self::update_state(
+                            states,
+                            (node, depth),
+                            &layout,
+                            EventType::MouseDown(cursor_event),
+                        );
 
                         if world.get::<Focusable>(node.0).is_some() {
                             Self::update_state(states, (node, depth), &layout, EventType::Focus);
@@ -578,7 +612,13 @@ impl EventDispatcher {
                 if let Some(layout) = context.get_layout(&node) {
                     if ignore_layout || layout.contains(&self.current_mouse_position) {
                         let cursor_event = self.get_cursor_event(self.current_mouse_position);
-                        event_stream.push(Event::new(node.0, EventType::MouseUp(cursor_event)));
+                        // event_stream.push(Event::new(node.0, EventType::MouseUp(cursor_event)));
+                        Self::update_state(
+                            states,
+                            (node, depth),
+                            &layout,
+                            EventType::MouseUp(cursor_event),
+                        );
                         // self.last_clicked.set(node);
 
                         if Self::contains_event(
@@ -701,11 +741,13 @@ impl EventDispatcher {
 
         let (node, depth) = tree_node;
         // Node is at or above best depth and is at or above best z-level
+
         let mut should_update = depth >= state.best_depth && layout.z_index >= state.best_z_index;
         // OR node is above best z-level
-        should_update |= layout.z_index > state.best_z_index;
+        should_update |= layout.z_index >= state.best_z_index;
 
         if should_update {
+            // dbg!(node.0.id(), layout.z_index);
             state.best_match = Some(node);
             state.best_z_index = layout.z_index;
             state.best_depth = depth;
diff --git a/src/node.rs b/src/node.rs
index 0fb1accf11a5318035e7e9568b751ecdba51719f..820e79d3c687ecdf9f7b3e18b0da33d364d42d84 100644
--- a/src/node.rs
+++ b/src/node.rs
@@ -23,6 +23,7 @@ pub struct Node {
     pub primitive: RenderPrimitive,
     /// The z-index of this node, used for controlling layering
     pub z: f32,
+    pub old_z: f32,
 }
 
 impl Default for Node {
@@ -34,6 +35,7 @@ impl Default for Node {
             raw_styles: Default::default(),
             primitive: RenderPrimitive::Empty,
             z: Default::default(),
+            old_z: Default::default(),
         }
     }
 }
@@ -54,6 +56,7 @@ impl NodeBuilder {
                 raw_styles: None,
                 primitive: RenderPrimitive::Empty,
                 z: 0.0,
+                old_z: 0.0,
             },
         }
     }
@@ -68,6 +71,7 @@ impl NodeBuilder {
                 raw_styles: None,
                 primitive: RenderPrimitive::Empty,
                 z: 0.0,
+                old_z: 0.0,
             },
         }
     }
diff --git a/src/render/unified/shader.wgsl b/src/render/unified/shader.wgsl
index e299a44a6e967e00c9a168c965d824f5cf0a44a7..3aac721a0c798a032e70f5400905a0753a5c9705 100644
--- a/src/render/unified/shader.wgsl
+++ b/src/render/unified/shader.wgsl
@@ -63,7 +63,7 @@ fn sdRoundBox(p: vec2<f32>, b: vec2<f32>, r: f32) -> f32 {
 
 @fragment
 fn fragment(in: VertexOutput) -> @location(0) vec4<f32> {
-    if (quad_type.t == 0) {
+    if quad_type.t == 0 {
         var size = in.size;
         var pos = in.pos.xy * 2.0;
         // Lock border to max size. This is similar to how HTML/CSS handles border radius.
@@ -76,8 +76,8 @@ fn fragment(in: VertexOutput) -> @location(0) vec4<f32> {
         rect_dist = 1.0 - smoothstep(0.0, fwidth(rect_dist), rect_dist);
         return vec4<f32>(in.color.rgb, rect_dist * in.color.a);
     }
-    if (quad_type.t == 1) {
-        var px_range = 3.5;
+    if quad_type.t == 1 {
+        var px_range = 5.0;
         var tex_dimensions = textureDimensions(font_texture);
         var msdf_unit = vec2<f32>(px_range, px_range) / vec2<f32>(f32(tex_dimensions.x), f32(tex_dimensions.y));
         var x = textureSample(font_texture, font_sampler, vec2<f32>(in.uv.x, 1.0 - in.uv.y), i32(in.uv.z));
@@ -86,7 +86,7 @@ fn fragment(in: VertexOutput) -> @location(0) vec4<f32> {
         var a = clamp(sig_dist + 0.5, 0.0, 1.0);
         return vec4<f32>(in.color.rgb, a);
     }
-    if (quad_type.t == 2) {
+    if quad_type.t == 2 {
         var bs = min(in.border_radius, min(in.size.x, in.size.y));
         var mask = sdRoundBox(
             in.pos.xy * 2.0 - (in.size.xy),
diff --git a/src/render_primitive.rs b/src/render_primitive.rs
index 9e11073d6519aaf0631d6e958d435c7c0c388935..799af3e6c2b5e75e9c7a570ebc45969408790848 100644
--- a/src/render_primitive.rs
+++ b/src/render_primitive.rs
@@ -56,6 +56,18 @@ impl RenderPrimitive {
             _ => (),
         }
     }
+
+    pub fn to_string(&self) -> String {
+        match self {
+            RenderPrimitive::Clip { .. } => "Clip".into(),
+            RenderPrimitive::Quad { .. } => "Quad".into(),
+            RenderPrimitive::Text { .. } => "Text".into(),
+            RenderPrimitive::Image { .. } => "Image".into(),
+            RenderPrimitive::NinePatch { .. } => "NinePatch".into(),
+            RenderPrimitive::TextureAtlas { .. } => "TextureAtlas".into(),
+            RenderPrimitive::Empty { .. } => "Empty".into(),
+        }
+    }
 }
 
 impl From<&KStyle> for RenderPrimitive {
diff --git a/src/styles/style.rs b/src/styles/style.rs
index dc8bb057393ea0a9319017dc48f876d51526ffcd..9decc31d6343c70a1e885d34c3336e1b821fc0c5 100644
--- a/src/styles/style.rs
+++ b/src/styles/style.rs
@@ -361,6 +361,8 @@ define_styles! {
         pub top: StyleProp<Units>,
         /// The width of this widget
         pub width: StyleProp<Units>,
+        /// The z-index relative to it's parent.
+        pub z_index: StyleProp<i32>,
     }
 }
 
@@ -402,6 +404,7 @@ impl KStyle {
             row_between: StyleProp::Default,
             top: StyleProp::Default,
             width: StyleProp::Default,
+            z_index: StyleProp::Default,
         }
     }
 }
diff --git a/src/tree.rs b/src/tree.rs
index 1f6453774a4383c56ff436d2a18538553f909fe1..5be5caf30633d70256452fb3300b0fdd1a34d2c4 100644
--- a/src/tree.rs
+++ b/src/tree.rs
@@ -78,10 +78,6 @@ impl Tree {
             children
         } else {
             // Is root node
-            self.root_node = None;
-            self.parents.clear();
-            self.children.clear();
-
             Vec::default()
         }
     }
@@ -358,7 +354,7 @@ impl Tree {
             .iter()
             .map(|(id, node, parent_node, change)| {
                 if change[0] == Change::Deleted {
-                    return (0, *node, *parent_node, change.clone());
+                    return (*id, *node, *parent_node, change.clone());
                 } else if change[0] == Change::Inserted {
                     let child_id = other_tree
                         .children
@@ -672,6 +668,10 @@ impl Tree {
             }
         }
     }
+
+    pub fn down_iter_at(&self, node: WrappedIndex, include_self: bool) -> DownwardIterator {
+        DownwardIterator::new(self, Some(node), include_self)
+    }
 }
 
 /// An iterator that performs a depth-first traversal down a tree starting
diff --git a/src/widget.rs b/src/widget.rs
index c079b2d35c72b40d8d162a8da805d87639a6abc0..f6e23819ebcd1c94932cb7c8851b9c8f91be86b9 100644
--- a/src/widget.rs
+++ b/src/widget.rs
@@ -38,6 +38,12 @@ pub fn widget_update_with_context<
     // Uses bevy state changes to see if context has changed.
     if let Some(context_entity) = widget_context.get_context_entity::<Context>(entity) {
         if context_query.contains(context_entity) {
+            log::trace!(
+                "Entity context: {} has changed! {}-{}",
+                std::any::type_name::<Context>(),
+                widget_param.widget_names.get(entity).unwrap().0,
+                entity.id()
+            );
             return true;
         }
     }
@@ -66,6 +72,11 @@ impl<'w, 's, Props: PartialEq + Component, State: PartialEq + Component>
         previous_entity: Entity,
     ) -> bool {
         if !self.mounted_query.is_empty() {
+            log::trace!(
+                "Entity was mounted! {}-{}",
+                self.widget_names.get(current_entity).unwrap().0,
+                current_entity.id()
+            );
             return true;
         }
 
@@ -91,6 +102,11 @@ impl<'w, 's, Props: PartialEq + Component, State: PartialEq + Component>
             self.children_query.get(previous_entity),
         ) {
             if children != old_children {
+                log::trace!(
+                    "Entity children have changed! {}-{}",
+                    self.widget_names.get(current_entity).unwrap().0,
+                    current_entity.id()
+                );
                 return true;
             }
         }
diff --git a/src/widget_context.rs b/src/widget_context.rs
index dd9cdb901f87df05627a0de15262220ac7b4a568..28c5839e311cb4b059c8c8b766824f133245fbfb 100644
--- a/src/widget_context.rs
+++ b/src/widget_context.rs
@@ -23,8 +23,9 @@ pub struct KayakWidgetContext {
     new_tree: Arc<RwLock<Tree>>,
     context_entities: ContextEntities,
     layout_cache: Arc<RwLock<LayoutCache>>,
-    index: Arc<RwLock<HashMap<Entity, usize>>>,
+    pub(crate) index: Arc<RwLock<HashMap<Entity, usize>>>,
     widget_state: WidgetState,
+    order_tree: Arc<RwLock<Tree>>,
 }
 
 impl KayakWidgetContext {
@@ -33,14 +34,17 @@ impl KayakWidgetContext {
         context_entities: ContextEntities,
         layout_cache: Arc<RwLock<LayoutCache>>,
         widget_state: WidgetState,
+        order_tree: Arc<RwLock<Tree>>,
+        index: Arc<RwLock<HashMap<Entity, usize>>>,
     ) -> Self {
         Self {
             old_tree,
             new_tree: Arc::new(RwLock::new(Tree::default())),
             context_entities,
             layout_cache,
-            index: Arc::new(RwLock::new(HashMap::default())),
+            index,
             widget_state,
+            order_tree,
         }
     }
 
@@ -121,9 +125,9 @@ impl KayakWidgetContext {
         children
     }
 
-    fn get_children_old(&self, entity: Entity) -> Vec<Entity> {
+    fn get_children_ordered(&self, entity: Entity) -> Vec<Entity> {
         let mut children = vec![];
-        if let Ok(tree) = self.old_tree.read() {
+        if let Ok(tree) = self.order_tree.read() {
             let iterator = tree.child_iter(WrappedIndex(entity));
 
             children = iterator.map(|index| index.0).collect::<Vec<_>>();
@@ -164,15 +168,42 @@ impl KayakWidgetContext {
         self.widget_state.get(widget_entity)
     }
 
-    /// Returns a child entity or none if it does not exist.
+    /// Returns a new/existing widget entity.
     /// Because a re-render can potentially spawn new entities it's advised to use this
     /// to avoid creating a new entity.
-    pub fn get_child_at(&self, entity: Option<Entity>) -> Option<Entity> {
-        if let Some(entity) = entity {
-            let children = self.get_children_old(entity);
-            return children.get(self.get_and_add_index(entity)).cloned();
+    pub fn spawn_widget(&self, commands: &mut Commands, parent_id: Option<Entity>) -> Entity {
+        let mut entity = None;
+        if let Some(parent_entity) = parent_id {
+            let children = self.get_children_ordered(parent_entity);
+            let index = self.get_and_add_index(parent_entity);
+            let child = children.get(index).cloned();
+            if let Some(child) = child {
+                log::trace!(
+                    "Reusing widget entity {:?} with parent: {:?}!",
+                    child.id(),
+                    parent_id.unwrap().id()
+                );
+                entity = Some(commands.get_or_spawn(child).id());
+            }
         }
-        None
+
+        // If we have no entity spawn it!
+        if entity.is_none() {
+            entity = Some(commands.spawn_empty().id());
+            log::trace!(
+                "Spawning new widget with entity {:?}!",
+                entity.unwrap().id()
+            );
+
+            // We need to add it to the ordered tree
+            if let Ok(mut tree) = self.order_tree.try_write() {
+                tree.add(
+                    WrappedIndex(entity.unwrap()),
+                    parent_id.and_then(|parent| Some(WrappedIndex(parent))),
+                )
+            }
+        }
+        entity.unwrap()
     }
 
     /// Removes all matching children from the tree.
@@ -186,6 +217,9 @@ impl KayakWidgetContext {
 
     /// Adds a new widget to the tree with a given parent.
     pub fn add_widget(&self, parent: Option<Entity>, entity: Entity) {
+        if let Some(parent) = parent {
+            assert!(parent != entity, "Parent cannot equal entity!");
+        }
         if let Ok(mut tree) = self.new_tree.write() {
             tree.add(
                 WrappedIndex(entity),
diff --git a/src/widgets/app.rs b/src/widgets/app.rs
index 8aa40a18504529547ed7ed89904b5b20e8d3d461..5d80ad7b86b26925fb65f1796c5333768750c536 100644
--- a/src/widgets/app.rs
+++ b/src/widgets/app.rs
@@ -1,4 +1,5 @@
 use bevy::prelude::*;
+use kayak_ui_macros::rsx;
 use morphorm::Units;
 
 use crate::{
@@ -10,6 +11,8 @@ use crate::{
     CameraUIKayak,
 };
 
+use super::ClipBundle;
+
 #[derive(Component, Default, Clone, PartialEq)]
 pub struct KayakApp;
 
@@ -60,7 +63,7 @@ pub fn app_update(
 /// TODO: USE CAMERA INSTEAD OF WINDOW!!
 pub fn app_render(
     In((widget_context, entity)): In<(KayakWidgetContext, Entity)>,
-    _: Commands,
+    mut commands: Commands,
     windows: Res<Windows>,
     mut query: Query<(&mut KStyle, &KChildren)>,
     camera: Query<&Camera, With<CameraUIKayak>>,
@@ -88,7 +91,13 @@ pub fn app_render(
             app_style.height = StyleProp::Value(Units::Pixels(height));
         }
         app_style.render_command = StyleProp::Value(RenderCommand::Layout);
-        children.process(&widget_context, Some(entity));
+        // children.process(&widget_context, Some(entity));
+        let parent_id = Some(entity);
+        rsx! {
+            <ClipBundle
+                children={children.clone()}
+            />
+        }
     }
 
     true
diff --git a/src/widgets/button.rs b/src/widgets/button.rs
index 30910648107f4f6ab9867f53e805ab352900fdb3..419a5a74de5424e7e48b2e596191b1f93c4e8e8b 100644
--- a/src/widgets/button.rs
+++ b/src/widgets/button.rs
@@ -2,17 +2,27 @@ use bevy::{
     prelude::{Bundle, Color, Commands, Component, Entity, In, Query},
     window::CursorIcon,
 };
+use kayak_font::Alignment;
+use kayak_ui_macros::rsx;
 
 use crate::{
     context::WidgetName,
+    event::{Event, EventType},
+    event_dispatcher::EventDispatcherContext,
     on_event::OnEvent,
     prelude::{KChildren, KayakWidgetContext, Units},
-    styles::{Corner, KCursorIcon, KStyle, RenderCommand, StyleProp},
+    styles::{Corner, Edge, KCursorIcon, KStyle, RenderCommand, StyleProp},
     widget::Widget,
+    widget_state::WidgetState,
 };
 
+use super::{ElementBundle, TextProps, TextWidgetBundle};
+
 #[derive(Component, PartialEq, Clone, Default)]
-pub struct KButton;
+pub struct KButton {
+    pub text: String,
+    pub user_styles: KStyle,
+}
 
 /// Default button widget
 /// Accepts an OnEvent component
@@ -21,7 +31,6 @@ pub struct KButtonBundle {
     pub button: KButton,
     pub styles: KStyle,
     pub on_event: OnEvent,
-    pub children: KChildren,
     pub widget_name: WidgetName,
 }
 
@@ -31,7 +40,6 @@ impl Default for KButtonBundle {
             button: Default::default(),
             styles: Default::default(),
             on_event: Default::default(),
-            children: KChildren::default(),
             widget_name: KButton::default().get_name(),
         }
     }
@@ -39,32 +47,95 @@ impl Default for KButtonBundle {
 
 impl Widget for KButton {}
 
+#[derive(Component, Default, Debug, Clone, PartialEq)]
+pub struct ButtonState {
+    hovering: bool,
+}
+
 pub fn button_render(
     In((widget_context, entity)): In<(KayakWidgetContext, Entity)>,
-    _: Commands,
-    mut query: Query<(&mut KStyle, &KChildren)>,
+    mut commands: Commands,
+    mut query: Query<(&KButton, &mut KStyle)>,
+    state_query: Query<&ButtonState>,
 ) -> bool {
-    if let Ok((mut style, children)) = query.get_mut(entity) {
-        *style = KStyle::default()
-            .with_style(KStyle {
-                render_command: StyleProp::Value(RenderCommand::Quad),
-                ..Default::default()
-            })
-            .with_style(style.clone())
-            .with_style(KStyle {
-                render_command: StyleProp::Value(RenderCommand::Quad),
-                background_color: StyleProp::Value(Color::rgba(0.0781, 0.0898, 0.101, 1.0)),
-                border_radius: StyleProp::Value(Corner::all(5.0)),
-                height: StyleProp::Value(Units::Pixels(45.0)),
-                padding_left: StyleProp::Value(Units::Stretch(1.0)),
-                padding_right: StyleProp::Value(Units::Stretch(1.0)),
-                padding_bottom: StyleProp::Value(Units::Stretch(1.0)),
-                padding_top: StyleProp::Value(Units::Stretch(1.0)),
-                cursor: StyleProp::Value(KCursorIcon(CursorIcon::Hand)),
-                ..Default::default()
-            });
+    if let Ok((button, mut style)) = query.get_mut(entity) {
+        let hover_color = Color::rgba(0.592, 0.627, 0.749, 1.0); //Color::rgba(0.549, 0.666, 0.933, 1.0);
+                                                                 // let color = Color::rgba(0.254, 0.270, 0.349, 1.0);
+        let state_entity =
+            widget_context.use_state(&mut commands, entity, ButtonState { hovering: false });
 
-        children.process(&widget_context, Some(entity));
+        if let Ok(state) = state_query.get(state_entity) {
+            *style = KStyle::default()
+                .with_style(KStyle {
+                    render_command: StyleProp::Value(RenderCommand::Quad),
+                    ..Default::default()
+                })
+                .with_style(button.user_styles.clone())
+                .with_style(KStyle {
+                    background_color: Color::rgba(0.254, 0.270, 0.349, 1.0).into(),
+                    border_color: if state.hovering {
+                        hover_color.into()
+                    } else {
+                        Color::rgba(0.254, 0.270, 0.349, 1.0).into()
+                    },
+                    border: Edge::all(2.0).into(),
+                    border_radius: StyleProp::Value(Corner::all(10.0)),
+                    height: StyleProp::Value(Units::Pixels(28.0)),
+                    width: Units::Stretch(1.0).into(),
+                    cursor: StyleProp::Value(KCursorIcon(CursorIcon::Hand)),
+                    ..Default::default()
+                });
+
+            let on_event = OnEvent::new(
+                move |In((event_dispatcher_context, _, mut event, _entity)): In<(
+                    EventDispatcherContext,
+                    WidgetState,
+                    Event,
+                    Entity,
+                )>,
+                      mut query: Query<&mut ButtonState>| {
+                    if let Ok(mut button) = query.get_mut(state_entity) {
+                        match event.event_type {
+                            EventType::MouseIn(..) => {
+                                event.stop_propagation();
+                                button.hovering = true;
+                            }
+                            EventType::MouseOut(..) => {
+                                button.hovering = false;
+                            }
+                            _ => {}
+                        }
+                    }
+                    (event_dispatcher_context, event)
+                },
+            );
+
+            let parent_id = Some(entity);
+            rsx! {
+                <ElementBundle
+                    styles={KStyle {
+                        width: Units::Stretch(1.0).into(),
+                        height: Units::Stretch(1.0).into(),
+                        ..Default::default()
+                    }}
+                    on_event={on_event}
+                >
+                    <TextWidgetBundle
+                        text={TextProps {
+                            alignment: Alignment::Middle,
+                            content: button.text.clone(),
+                            size: 16.0,
+                            user_styles: KStyle {
+                                top: Units::Stretch(1.0).into(),
+                                bottom: Units::Stretch(1.0).into(),
+                                ..Default::default()
+                            },
+                            ..Default::default()
+                        }}
+                    />
+                </ElementBundle>
+            }
+        }
     }
 
     true
diff --git a/src/widgets/clip.rs b/src/widgets/clip.rs
index 8f81862f859f26402459b6ff9f11dedd0eda492e..386bae97bccfe16775ebac712739b440a4a81977 100644
--- a/src/widgets/clip.rs
+++ b/src/widgets/clip.rs
@@ -45,9 +45,10 @@ impl Default for ClipBundle {
 pub fn clip_render(
     In((widget_context, entity)): In<(KayakWidgetContext, Entity)>,
     _: Commands,
-    mut query: Query<(&KStyle, &KChildren)>,
+    mut query: Query<(&mut KStyle, &KChildren)>,
 ) -> bool {
-    if let Ok((_, children)) = query.get_mut(entity) {
+    if let Ok((mut styles, children)) = query.get_mut(entity) {
+        styles.render_command = StyleProp::Value(RenderCommand::Clip);
         children.process(&widget_context, Some(entity));
     }
     true
diff --git a/src/widgets/mod.rs b/src/widgets/mod.rs
index 586c634c30c368906b914f7fa79bca70c7418b20..a11e2cb6997d9d3555b66fa58f599ef61b93fe8d 100644
--- a/src/widgets/mod.rs
+++ b/src/widgets/mod.rs
@@ -34,10 +34,11 @@ mod text;
 mod text_box;
 mod texture_atlas;
 mod window;
+mod window_context_provider;
 
 pub use app::{KayakApp, KayakAppBundle};
 pub use background::{Background, BackgroundBundle};
-pub use button::{KButton, KButtonBundle};
+pub use button::{ButtonState, KButton, KButtonBundle};
 pub use clip::{Clip, ClipBundle};
 pub use element::{Element, ElementBundle};
 pub use image::{KImage, KImageBundle};
@@ -53,7 +54,10 @@ pub use scroll::{
 pub use text::{TextProps, TextWidgetBundle};
 pub use text_box::{TextBoxBundle, TextBoxProps, TextBoxState};
 pub use texture_atlas::{TextureAtlasBundle, TextureAtlasProps};
-pub use window::{KWindow, WindowBundle};
+pub use window::{KWindow, KWindowState, WindowBundle};
+pub use window_context_provider::{
+    WindowContext, WindowContextProvider, WindowContextProviderBundle,
+};
 
 use app::{app_render, app_update};
 use background::background_render;
@@ -76,7 +80,7 @@ use crate::{
     widget::{widget_update, widget_update_with_context, EmptyState, Widget},
 };
 
-use self::window::KWindowState;
+use self::window_context_provider::window_context_render;
 
 pub struct KayakWidgets;
 
@@ -88,9 +92,10 @@ impl Plugin for KayakWidgets {
 
 fn add_widget_systems(mut context: ResMut<KayakRootContext>) {
     context.add_widget_data::<KayakApp, EmptyState>();
-    context.add_widget_data::<KButton, EmptyState>();
+    context.add_widget_data::<KButton, ButtonState>();
     context.add_widget_data::<TextProps, EmptyState>();
     context.add_widget_data::<KWindow, KWindowState>();
+    context.add_widget_data::<WindowContextProvider, EmptyState>();
     context.add_widget_data::<Background, EmptyState>();
     context.add_widget_data::<Clip, EmptyState>();
     context.add_widget_data::<KImage, EmptyState>();
@@ -106,7 +111,7 @@ fn add_widget_systems(mut context: ResMut<KayakRootContext>) {
     context.add_widget_system(KayakApp::default().get_name(), app_update, app_render);
     context.add_widget_system(
         KButton::default().get_name(),
-        widget_update::<KButton, EmptyState>,
+        widget_update::<KButton, ButtonState>,
         button_render,
     );
     context.add_widget_system(
@@ -114,9 +119,14 @@ fn add_widget_systems(mut context: ResMut<KayakRootContext>) {
         widget_update::<TextProps, EmptyState>,
         text_render,
     );
+    context.add_widget_system(
+        WindowContextProvider::default().get_name(),
+        widget_update::<WindowContextProvider, EmptyState>,
+        window_context_render,
+    );
     context.add_widget_system(
         KWindow::default().get_name(),
-        widget_update::<KWindow, KWindowState>,
+        widget_update_with_context::<KWindow, KWindowState, WindowContext>,
         window_render,
     );
     context.add_widget_system(
diff --git a/src/widgets/scroll/scroll_bar.rs b/src/widgets/scroll/scroll_bar.rs
index f56c75471b9341eea014458a50d4625bc30d362f..5d63688c0f821033014020d579383eb41126f1ce 100644
--- a/src/widgets/scroll/scroll_bar.rs
+++ b/src/widgets/scroll/scroll_bar.rs
@@ -78,7 +78,7 @@ pub fn scroll_bar_render(
                 let thickness = scrollbar.thickness;
                 let thumb_color = scrollbar
                     .thumb_color
-                    .unwrap_or_else(|| Color::rgba(0.2981, 0.3098, 0.321, 0.95));
+                    .unwrap_or_else(|| Color::rgba(0.239, 0.258, 0.337, 1.0));
                 let thumb_styles = scrollbar.thumb_styles.clone();
                 let track_color = scrollbar
                     .track_color
diff --git a/src/widgets/scroll/scroll_box.rs b/src/widgets/scroll/scroll_box.rs
index b294e4aa8084011719aade89ac1dfc82c789a579..60eb4df118e7cfbdfe78e55ff151097019321871 100644
--- a/src/widgets/scroll/scroll_box.rs
+++ b/src/widgets/scroll/scroll_box.rs
@@ -85,7 +85,7 @@ pub fn scroll_box_render(
     if let Ok((scroll_box, mut styles, scroll_box_children, mut on_layout)) = query.get_mut(entity)
     {
         if let Some(context_entity) = widget_context.get_context_entity::<ScrollContext>(entity) {
-            if let Ok(scroll_context) = context_query.p1().get(context_entity).cloned() {
+            if let Ok(scroll_context) = context_query.p0().get(context_entity).cloned() {
                 // === Configuration === //
                 let always_show_scrollbar = scroll_box.always_show_scrollbar;
                 let disable_horizontal = scroll_box.disable_horizontal;
diff --git a/src/widgets/scroll/scroll_content.rs b/src/widgets/scroll/scroll_content.rs
index e3af6da6199e0afdc0f557a34c7bc9ae2f437305..4f2a2fea26e67a7b260c13daa8bad14a360afdec 100644
--- a/src/widgets/scroll/scroll_content.rs
+++ b/src/widgets/scroll/scroll_content.rs
@@ -70,7 +70,7 @@ pub fn scroll_content_render(
                         render_command: RenderCommand::Layout.into(),
                         layout_type: LayoutType::Column.into(),
                         min_width: Units::Pixels(
-                            scroll_context.scrollbox_width - scroll_context.pad_x,
+                            scroll_context.scrollbox_width - scroll_context.pad_x - 10.0,
                         )
                         .into(),
                         min_height: Units::Stretch(
diff --git a/src/widgets/text.rs b/src/widgets/text.rs
index 467628e57451296eb1649b64475d9b9ec8b6b4a7..790272daeeb34bf4bded21fd338e99a08804e0bd 100644
--- a/src/widgets/text.rs
+++ b/src/widgets/text.rs
@@ -1,5 +1,6 @@
 use bevy::prelude::*;
 use kayak_font::Alignment;
+use kayak_ui_macros::rsx;
 
 use crate::{
     context::WidgetName,
@@ -8,6 +9,8 @@ use crate::{
     widget::Widget,
 };
 
+use super::ElementBundle;
+
 #[derive(Component, Debug, PartialEq, Clone)]
 pub struct TextProps {
     /// The string to display
@@ -28,6 +31,8 @@ pub struct TextProps {
     pub size: f32,
     /// Text alignment.
     pub alignment: Alignment,
+    /// Custom styles to pass in.
+    pub user_styles: KStyle,
 }
 
 impl Default for TextProps {
@@ -39,6 +44,7 @@ impl Default for TextProps {
             show_cursor: false,
             size: -1.0,
             alignment: Alignment::Start,
+            user_styles: Default::default(),
         }
     }
 }
@@ -58,36 +64,60 @@ impl Default for TextWidgetBundle {
     fn default() -> Self {
         Self {
             text: Default::default(),
-            styles: Default::default(),
+            styles: KStyle {
+                ..Default::default()
+            },
             widget_name: TextProps::default().get_name(),
         }
     }
 }
 
 pub fn text_render(
-    In((_, entity)): In<(KayakWidgetContext, Entity)>,
-    mut query: Query<(&mut KStyle, &TextProps)>,
+    In((widget_context, entity)): In<(KayakWidgetContext, Entity)>,
+    mut commands: Commands,
+    mut query: Query<&TextProps>,
 ) -> bool {
-    if let Ok((mut style, text)) = query.get_mut(entity) {
-        style.render_command = StyleProp::Value(RenderCommand::Text {
-            content: text.content.clone(),
-            alignment: text.alignment,
-        });
+    if let Ok(text) = query.get_mut(entity) {
+        let mut style = KStyle::default();
 
-        if let Some(ref font) = text.font {
-            style.font = StyleProp::Value(font.clone());
-        }
-        if text.show_cursor {
-            style.cursor = StyleProp::Value(KCursorIcon(CursorIcon::Text));
-        }
-        if text.size >= 0.0 {
-            style.font_size = StyleProp::Value(text.size);
-        }
-        if let Some(line_height) = text.line_height {
-            style.line_height = StyleProp::Value(line_height);
-        }
+        style = style.with_style(&text.user_styles).with_style(KStyle {
+            render_command: StyleProp::Value(RenderCommand::Text {
+                content: text.content.clone(),
+                alignment: text.alignment,
+            }),
+            font: if let Some(ref font) = text.font {
+                StyleProp::Value(font.clone())
+            } else {
+                StyleProp::default()
+            },
+            cursor: if text.show_cursor {
+                StyleProp::Value(KCursorIcon(CursorIcon::Text))
+            } else {
+                StyleProp::default()
+            },
+            font_size: if text.size >= 0.0 {
+                StyleProp::Value(text.size)
+            } else {
+                StyleProp::default()
+            },
+            line_height: if let Some(line_height) = text.line_height {
+                StyleProp::Value(line_height)
+            } else {
+                StyleProp::default()
+            },
+            // bottom: Units::Stretch(1.0).into(),
+            // top: Units::Stretch(1.0).into(),
+            // left: Units::Stretch(0.0).into(),
+            // right: Units::Stretch(0.0).into(),
+            ..Default::default()
+        });
 
         // style.cursor = StyleProp::Value(KCursorIcon(CursorIcon::Hand));
+
+        let parent_id = Some(entity);
+        rsx! {
+            <ElementBundle styles={style} />
+        }
     }
 
     true
diff --git a/src/widgets/text_box.rs b/src/widgets/text_box.rs
index b66738c1965bddf77c02117e578b1e53331261f6..5c92aa98dbd07d6234af538bb4fd09f1e749ca44 100644
--- a/src/widgets/text_box.rs
+++ b/src/widgets/text_box.rs
@@ -8,7 +8,7 @@ use crate::{
     on_event::OnEvent,
     on_layout::OnLayout,
     prelude::{KChildren, KayakWidgetContext, OnChange},
-    styles::{Corner, KStyle, RenderCommand, StyleProp, Units},
+    styles::{Edge, KStyle, RenderCommand, StyleProp, Units},
     widget::Widget,
     widget_state::WidgetState,
     widgets::{
@@ -74,6 +74,7 @@ pub fn text_box_render(
     In((widget_context, entity)): In<(KayakWidgetContext, Entity)>,
     mut commands: Commands,
     mut query: Query<(&mut KStyle, &TextBoxProps, &mut OnEvent, &OnChange)>,
+    state_query: Query<&TextBoxState>,
 ) -> bool {
     if let Ok((mut styles, text_box, mut on_event, on_change)) = query.get_mut(entity) {
         let state_entity = widget_context.use_state::<TextBoxState>(
@@ -82,102 +83,114 @@ pub fn text_box_render(
             TextBoxState::default(),
         );
 
-        *styles = KStyle::default()
-            // Required styles
-            .with_style(KStyle {
-                render_command: RenderCommand::Layout.into(),
-                ..Default::default()
-            })
-            // Apply any prop-given styles
-            .with_style(&*styles)
-            // If not set by props, apply these styles
-            .with_style(KStyle {
-                top: Units::Pixels(0.0).into(),
-                bottom: Units::Pixels(0.0).into(),
+        if let Ok(state) = state_query.get(state_entity) {
+            *styles = KStyle::default()
+                // Required styles
+                .with_style(KStyle {
+                    render_command: RenderCommand::Layout.into(),
+                    ..Default::default()
+                })
+                // Apply any prop-given styles
+                .with_style(&*styles)
+                // If not set by props, apply these styles
+                .with_style(KStyle {
+                    top: Units::Pixels(0.0).into(),
+                    bottom: Units::Pixels(0.0).into(),
+                    height: Units::Pixels(26.0).into(),
+                    // cursor: CursorIcon::Text.into(),
+                    ..Default::default()
+                });
+
+            let background_styles = KStyle {
+                render_command: StyleProp::Value(RenderCommand::Quad),
+                background_color: Color::rgba(0.160, 0.172, 0.235, 1.0).into(),
+                border_color: if state.focused {
+                    Color::rgba(0.933, 0.745, 0.745, 1.0).into()
+                } else {
+                    Color::rgba(0.360, 0.380, 0.474, 1.0).into()
+                },
+                border: Edge::new(0.0, 0.0, 0.0, 2.0).into(),
                 height: Units::Pixels(26.0).into(),
-                // cursor: CursorIcon::Text.into(),
+                padding_left: Units::Pixels(5.0).into(),
+                padding_right: Units::Pixels(5.0).into(),
                 ..Default::default()
-            });
-
-        let background_styles = KStyle {
-            render_command: StyleProp::Value(RenderCommand::Quad),
-            background_color: StyleProp::Value(Color::rgba(0.176, 0.196, 0.215, 1.0)),
-            border_radius: Corner::all(5.0).into(),
-            height: Units::Pixels(26.0).into(),
-            padding_left: Units::Pixels(5.0).into(),
-            padding_right: Units::Pixels(5.0).into(),
-            ..Default::default()
-        };
+            };
 
-        let current_value = text_box.value.clone();
-        let cloned_on_change = on_change.clone();
+            let current_value = text_box.value.clone();
+            let cloned_on_change = on_change.clone();
 
-        *on_event = OnEvent::new(
-            move |In((event_dispatcher_context, _, mut event, _entity)): In<(
-                EventDispatcherContext,
-                WidgetState,
-                Event,
-                Entity,
-            )>,
-                  mut state_query: Query<&mut TextBoxState>| {
-                match event.event_type {
-                    EventType::CharInput { c } => {
-                        let mut current_value = current_value.clone();
-                        let cloned_on_change = cloned_on_change.clone();
-                        if let Ok(state) = state_query.get(state_entity) {
-                            if !state.focused {
+            *on_event = OnEvent::new(
+                move |In((event_dispatcher_context, _, mut event, _entity)): In<(
+                    EventDispatcherContext,
+                    WidgetState,
+                    Event,
+                    Entity,
+                )>,
+                      mut state_query: Query<&mut TextBoxState>| {
+                    match event.event_type {
+                        EventType::CharInput { c } => {
+                            let mut current_value = current_value.clone();
+                            let cloned_on_change = cloned_on_change.clone();
+                            if let Ok(state) = state_query.get(state_entity) {
+                                if !state.focused {
+                                    return (event_dispatcher_context, event);
+                                }
+                            } else {
                                 return (event_dispatcher_context, event);
                             }
-                        } else {
-                            return (event_dispatcher_context, event);
-                        }
-                        if is_backspace(c) {
-                            if !current_value.is_empty() {
-                                current_value.truncate(current_value.len() - 1);
+                            if is_backspace(c) {
+                                if !current_value.is_empty() {
+                                    current_value.truncate(current_value.len() - 1);
+                                }
+                            } else if !c.is_control() {
+                                current_value.push(c);
                             }
-                        } else if !c.is_control() {
-                            current_value.push(c);
+                            cloned_on_change.set_value(current_value);
+                            event.add_system(cloned_on_change);
                         }
-                        cloned_on_change.set_value(current_value);
-                        event.add_system(cloned_on_change);
-                    }
-                    EventType::Focus => {
-                        if let Ok(mut state) = state_query.get_mut(state_entity) {
-                            state.focused = true;
+                        EventType::Focus => {
+                            if let Ok(mut state) = state_query.get_mut(state_entity) {
+                                state.focused = true;
+                            }
                         }
-                    }
-                    EventType::Blur => {
-                        if let Ok(mut state) = state_query.get_mut(state_entity) {
-                            state.focused = false;
+                        EventType::Blur => {
+                            if let Ok(mut state) = state_query.get_mut(state_entity) {
+                                state.focused = false;
+                            }
                         }
+                        _ => {}
                     }
-                    _ => {}
-                }
-                (event_dispatcher_context, event)
-            },
-        );
+                    (event_dispatcher_context, event)
+                },
+            );
 
-        let parent_id = Some(entity);
-        rsx! {
-            <BackgroundBundle styles={background_styles}>
-                <ClipBundle styles={KStyle {
-                    height: Units::Pixels(26.0).into(),
-                    padding_left: StyleProp::Value(Units::Stretch(0.0)),
-                    padding_right: StyleProp::Value(Units::Stretch(0.0)),
-                    padding_bottom: StyleProp::Value(Units::Stretch(1.0)),
-                    padding_top: StyleProp::Value(Units::Stretch(1.0)),
-                    ..Default::default()
-                }}>
-                    <TextWidgetBundle
-                        text={TextProps {
-                            content: text_box.value.clone(),
-                            size: 14.0,
-                            line_height: Some(18.0),
-                            ..Default::default()
-                        }}
-                    />
-                </ClipBundle>
-            </BackgroundBundle>
+            let parent_id = Some(entity);
+            rsx! {
+                <BackgroundBundle styles={background_styles}>
+                    <ClipBundle styles={KStyle {
+                        height: Units::Pixels(26.0).into(),
+                        padding_left: StyleProp::Value(Units::Stretch(0.0)),
+                        padding_right: StyleProp::Value(Units::Stretch(0.0)),
+                        padding_bottom: StyleProp::Value(Units::Stretch(1.0)),
+                        padding_top: StyleProp::Value(Units::Stretch(1.0)),
+                        ..Default::default()
+                    }}>
+                        <TextWidgetBundle
+                            text={TextProps {
+                                content: text_box.value.clone(),
+                                size: 14.0,
+                                line_height: Some(18.0),
+                                user_styles: KStyle {
+                                    top: Units::Stretch(1.0).into(),
+                                    bottom: Units::Stretch(1.0).into(),
+                                    ..Default::default()
+                                },
+                                ..Default::default()
+                            }}
+                        />
+                    </ClipBundle>
+                </BackgroundBundle>
+            }
         }
     }
 
diff --git a/src/widgets/window.rs b/src/widgets/window.rs
index d51c0f5d7bb2976d8980eddd16a4ffb71cd12c51..6ccf5ba29bd5c3aa325ef019b7aa8cc11519b91f 100644
--- a/src/widgets/window.rs
+++ b/src/widgets/window.rs
@@ -14,12 +14,14 @@ use crate::{
     styles::{Corner, Edge, KCursorIcon, KPositionType, KStyle, RenderCommand, StyleProp, Units},
     widget::Widget,
     widget_state::WidgetState,
+    Focusable,
 };
 
 use super::{
     background::BackgroundBundle,
     clip::ClipBundle,
     text::{TextProps, TextWidgetBundle},
+    window_context_provider::WindowContext,
     ElementBundle,
 };
 
@@ -33,6 +35,10 @@ pub struct KWindow {
     pub size: Vec2,
     /// The text to display in the window's title bar
     pub title: String,
+    /// Styles for the main window quad.
+    pub window_styles: KStyle,
+    /// A set of styles to apply to the children element wrapper.
+    pub children_styles: KStyle,
 }
 
 #[derive(Component, PartialEq, Clone, Debug, Default)]
@@ -40,6 +46,7 @@ pub struct KWindowState {
     pub is_dragging: bool,
     pub offset: Vec2,
     pub position: Vec2,
+    pub focused: bool,
 }
 
 impl Widget for KWindow {}
@@ -69,10 +76,29 @@ impl Default for WindowBundle {
 pub fn window_render(
     In((widget_context, window_entity)): In<(KayakWidgetContext, Entity)>,
     mut commands: Commands,
-    mut query: Query<(&KStyle, &KChildren, &KWindow)>,
+    mut query: Query<(&mut KStyle, &KChildren, &KWindow)>,
     state_query: Query<&KWindowState>,
+    mut context_query: Query<&mut WindowContext>,
 ) -> bool {
-    if let Ok((window_style, window_children, window)) = query.get_mut(window_entity) {
+    if let Ok((mut window_style, window_children, window)) = query.get_mut(window_entity) {
+        let possible_context_entity =
+            widget_context.get_context_entity::<WindowContext>(window_entity);
+        let z_index = if let Some(window_context_entity) = possible_context_entity {
+            if let Ok(mut window_context) = context_query.get_mut(window_context_entity) {
+                Some(window_context.get_or_add(window_entity))
+            } else {
+                None
+            }
+        } else {
+            None
+        };
+
+        window_style.z_index = if z_index.is_some() {
+            StyleProp::Value(z_index.unwrap() as i32 * 1000)
+        } else {
+            StyleProp::Default
+        };
+
         let title = window.title.clone();
 
         let state_entity = widget_context.use_state(
@@ -82,18 +108,55 @@ pub fn window_render(
                 position: window.initial_position,
                 offset: Vec2::ZERO,
                 is_dragging: false,
+                focused: false,
             },
         );
 
         if let Ok(state) = state_query.get(state_entity) {
             let parent_id = Some(window_entity);
+
+            let focus_event = OnEvent::new(
+                move |In((event_dispatcher_context, _, mut event, _entity)): In<(
+                    EventDispatcherContext,
+                    WidgetState,
+                    Event,
+                    Entity,
+                )>,
+                      mut query: Query<&mut KWindowState>,
+                      mut context_query: Query<&mut WindowContext>| {
+                    if let Ok(mut window) = query.get_mut(state_entity) {
+                        event.stop_propagation();
+                        event.prevent_default();
+                        match event.event_type {
+                            EventType::Focus => {
+                                window.focused = true;
+                                if let Some(window_context_entity) = possible_context_entity {
+                                    if let Ok(mut context) =
+                                        context_query.get_mut(window_context_entity)
+                                    {
+                                        context.shift_to_top(window_entity);
+                                    }
+                                }
+                            }
+                            EventType::Blur => {
+                                window.focused = false;
+                                window.is_dragging = false;
+                            }
+                            _ => {}
+                        }
+                    }
+                    (event_dispatcher_context, event)
+                },
+            );
+
             rsx! {
                 <ElementBundle
-                    styles={KStyle {
-                        background_color: StyleProp::Value(Color::rgba(0.125, 0.125, 0.125, 1.0)),
-                        border_color: StyleProp::Value(Color::rgba(0.0781, 0.0898, 0.101, 1.0)),
-                        border: StyleProp::Value(Edge::all(4.0)),
-                        border_radius: StyleProp::Value(Corner::all(5.0)),
+                    id={"window_entity"}
+                    styles={window.window_styles.clone().with_style(KStyle {
+                        background_color: StyleProp::Value(Color::rgba(0.188, 0.203, 0.274, 1.0)),
+                        border_color: StyleProp::Value(if state.focused { Color::rgba(0.933, 0.745, 0.745, 1.0) } else { Color::rgba(0.239, 0.258, 0.337, 1.0) }),
+                        border: StyleProp::Value(Edge::all(2.0)),
+                        border_radius: StyleProp::Value(Corner::all(10.0)),
                         render_command: StyleProp::Value(RenderCommand::Quad),
                         position_type: StyleProp::Value(KPositionType::SelfDirected),
                         left: StyleProp::Value(Units::Pixels(state.position.x)),
@@ -102,16 +165,18 @@ pub fn window_render(
                         height: StyleProp::Value(Units::Pixels(window.size.y)),
                         min_width: StyleProp::Value(Units::Pixels(window.size.x)),
                         min_height: StyleProp::Value(Units::Pixels(window.size.y)),
-                        ..window_style.clone()
-                    }}
+                        ..Default::default()
+                    })}
+                    on_event={focus_event}
                 >
+                    {commands.entity(window_entity).insert(Focusable)}
                     <BackgroundBundle
                         id={"title_bar_entity"}
                         styles={KStyle {
                             cursor: StyleProp::Value(KCursorIcon(CursorIcon::Hand)),
                             render_command: StyleProp::Value(RenderCommand::Quad),
-                            background_color: StyleProp::Value(Color::rgba(0.0781, 0.0898, 0.101, 1.0)),
-                            border_radius: StyleProp::Value(Corner::all(5.0)),
+                            background_color: StyleProp::Value(Color::rgba(0.188, 0.203, 0.274, 1.0)),
+                            border_radius: Corner::all(10.0).into(),
                             height: StyleProp::Value(Units::Pixels(24.0)),
                             width: StyleProp::Value(Units::Stretch(1.0)),
                             left: StyleProp::Value(Units::Pixels(0.0)),
@@ -119,6 +184,8 @@ pub fn window_render(
                             top: StyleProp::Value(Units::Pixels(0.0)),
                             bottom: StyleProp::Value(Units::Pixels(0.0)),
                             padding_left: StyleProp::Value(Units::Pixels(5.0)),
+                            padding_top: Units::Stretch(1.0).into(),
+                            padding_bottom: Units::Stretch(1.0).into(),
                             ..KStyle::default()
                         }}
                     >
@@ -126,21 +193,24 @@ pub fn window_render(
                             text={TextProps {
                                 content: title.clone(),
                                 size: 14.0,
-                                line_height: Some(25.0),
+                                user_styles: KStyle {
+                                    top: Units::Stretch(1.0).into(),
+                                    bottom: Units::Stretch(1.0).into(),
+                                    ..Default::default()
+                                },
                                 ..Default::default()
                             }}
-                            styles={KStyle {
-                                height: StyleProp::Value(Units::Pixels(25.0)),
-                                ..KStyle::default()
-                            }}
                         />
                     </BackgroundBundle>
                     {
+                        // This code needs to go after the closing tag for the background bundle as that is when the
+                        // widget is "spawned". Adding this code after just the starting tag will cause this OnEvent
+                        // to be wiped out with a default version.
                         if window.draggable {
                             commands
                                 .entity(title_bar_entity)
                                 .insert(OnEvent::new(
-                                    move |In((mut event_dispatcher_context, _, event, entity)): In<(
+                                    move |In((mut event_dispatcher_context, _, mut event, entity)): In<(
                                         EventDispatcherContext,
                                         WidgetState,
                                         Event,
@@ -148,6 +218,8 @@ pub fn window_render(
                                     )>,
                                         mut query: Query<&mut KWindowState>| {
                                         if let Ok(mut window) = query.get_mut(state_entity) {
+                                            event.prevent_default();
+                                            event.stop_propagation();
                                             match event.event_type {
                                                 EventType::MouseDown(data) => {
                                                     event_dispatcher_context.capture_cursor(entity);
@@ -177,14 +249,22 @@ pub fn window_render(
                                 ));
                         }
                     }
-                    <ClipBundle
+                    <BackgroundBundle
                         styles={KStyle {
+                            background_color: StyleProp::Value(Color::rgba(0.239, 0.258, 0.337, 1.0)),
+                            width: Units::Stretch(1.0).into(),
+                            height: Units::Pixels(2.0).into(),
+                            ..Default::default()
+                        }}
+                    />
+                    <ClipBundle
+                        styles={window.children_styles.clone().with_style(KStyle {
                             top: Units::Pixels(10.0).into(),
                             left: Units::Pixels(10.0).into(),
                             right: Units::Pixels(10.0).into(),
                             bottom: Units::Pixels(10.0).into(),
                             ..Default::default()
-                        }}
+                        })}
                         children={window_children.clone()}
                     />
                 </ElementBundle>
diff --git a/src/widgets/window_context_provider.rs b/src/widgets/window_context_provider.rs
new file mode 100644
index 0000000000000000000000000000000000000000..6e424c55db0b5540fb448c1d32c0b2e6fb0b6b01
--- /dev/null
+++ b/src/widgets/window_context_provider.rs
@@ -0,0 +1,81 @@
+use bevy::{prelude::*, utils::HashMap};
+
+use crate::{
+    children::KChildren, context::WidgetName, prelude::KayakWidgetContext, widget::Widget,
+};
+
+#[derive(Component, Default, Debug, Clone, PartialEq)]
+pub struct WindowContext {
+    order: Vec<Entity>,
+    z_indices: HashMap<Entity, usize>,
+}
+
+impl WindowContext {
+    pub fn add(&mut self, entity: Entity, index: usize) {
+        self.order.push(entity);
+        self.z_indices.insert(entity, index);
+    }
+
+    pub fn shift_to_top(&mut self, entity: Entity) {
+        if let Some(index) = self.order.iter().position(|e| e.id() == entity.id()) {
+            self.order.remove(index);
+            self.order.push(entity);
+        }
+
+        self.z_indices.clear();
+        for (index, entity) in self.order.iter().enumerate() {
+            self.z_indices.insert(*entity, index);
+        }
+    }
+
+    pub fn get(&self, entity: Entity) -> usize {
+        *self.z_indices.get(&entity).unwrap()
+    }
+
+    pub fn get_or_add(&mut self, entity: Entity) -> usize {
+        if self.order.iter().any(|e| e.id() == entity.id()) {
+            self.get(entity)
+        } else {
+            self.add(entity, 0);
+            self.shift_to_top(entity);
+            self.get(entity)
+        }
+    }
+}
+
+#[derive(Component, Default, Debug, Clone, PartialEq)]
+pub struct WindowContextProvider;
+
+impl Widget for WindowContextProvider {}
+
+#[derive(Bundle, Debug, Clone, PartialEq)]
+pub struct WindowContextProviderBundle {
+    pub context_provider: WindowContextProvider,
+    pub children: KChildren,
+    pub widget_name: WidgetName,
+}
+
+impl Default for WindowContextProviderBundle {
+    fn default() -> Self {
+        Self {
+            context_provider: Default::default(),
+            children: Default::default(),
+            widget_name: WindowContextProvider::default().get_name(),
+        }
+    }
+}
+
+pub fn window_context_render(
+    In((widget_context, window_context_entity)): In<(KayakWidgetContext, Entity)>,
+    mut commands: Commands,
+    children_query: Query<&KChildren>,
+) -> bool {
+    if let Ok(children) = children_query.get(window_context_entity) {
+        let context_entity = commands.spawn(WindowContext::default()).id();
+        widget_context
+            .set_context_entity::<WindowContext>(Some(window_context_entity), context_entity);
+        children.process(&widget_context, Some(window_context_entity));
+    }
+
+    true
+}