diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt
index ec4cb1b2a9973512ce7d80717d6b19128d15c3a3..7637c65e7e1e7a25f71a69fa3940646452606cdd 100644
--- a/examples/CMakeLists.txt
+++ b/examples/CMakeLists.txt
@@ -1,4 +1,8 @@
 add_subdirectory(frame)
 add_subdirectory(gauge)
+add_subdirectory(menu)
+add_subdirectory(menu2)
+add_subdirectory(print_key_press)
 add_subdirectory(separator)
 add_subdirectory(vbox_hbox)
+add_subdirectory(toggle)
diff --git a/examples/frame/main.cpp b/examples/frame/main.cpp
index 7b155cc205aa7bf5db9439a8d511d00befd74625..329d0041d6db719e8bce1d1795536c246b6def2b 100644
--- a/examples/frame/main.cpp
+++ b/examples/frame/main.cpp
@@ -2,33 +2,47 @@
 #include <iostream>
 #include <thread>
 
-#include "ftxui/core/screen.hpp"
-#include "ftxui/core/dom/elements.hpp"
+#include "ftxui/screen.hpp"
+#include "ftxui/dom/elements.hpp"
 
 int main(int argc, const char *argv[])
 {
   using namespace ftxui::dom;
-  auto document =
-    hbox(
-      frame(
-        vbox(
-          text(L"Line 1"),
-          text(L"Line 2"),
-          text(L"Line 3"),
-          frame(
-            vbox(
-              text(L"Line 4"),
-              text(L"Line 5"),
-              text(L"Line 6")
-            )
-          ),
-          text(L"Line 7"),
-          text(L"Line 8"),
-          text(L"Line 9")
-        )
-      ),
-      flex()
-    );
+	auto document =
+		hbox(
+			frame(hcenter(text(L" main frame ")),
+				vbox(
+					text(L"Line 1"),
+					text(L"Line 2"),
+					text(L"Line 3"),
+					frame(
+						vbox(
+							text(L"Line 4"),
+							text(L"Line 5"),
+							text(L"Line 6")
+						)
+					),
+					hbox(
+						frame(text(L"frame 2"),
+							vbox(
+								text(L"Line 4"),
+								text(L"Line 5"),
+								text(L"Line 6")
+							)
+						),
+						frame(text(L"frame 3"),
+							vbox(
+								text(L"Line 7"),
+								text(L"Line 8"),
+								text(L"Line 9")
+							)
+						)
+					),
+					text(L"footer footer footer footer footer")
+				)
+			),
+			flex()
+		);
   auto screen = ftxui::Screen::TerminalOutput(document);
   Render(screen, document.get());
   std::cout << screen.ToString() << std::endl;
diff --git a/examples/gauge/main.cpp b/examples/gauge/main.cpp
index ab45ec2b0bb2ef80154d2689d51111f447499413..64ec77b2a979715c2e3cbc70231ddb800c722eb3 100644
--- a/examples/gauge/main.cpp
+++ b/examples/gauge/main.cpp
@@ -2,15 +2,21 @@
 #include <iostream>
 #include <thread>
 
-#include "ftxui/core/screen.hpp"
-#include "ftxui/core/dom/elements.hpp"
+#include "ftxui/screen.hpp"
+#include "ftxui/dom/elements.hpp"
 
 int main(int argc, const char *argv[])
 {
   for(float percentage = 0; percentage <= 1.0; percentage+=0.001) {
+    std::wstring data_downloaded =
+        std::to_wstring(int(percentage * 44100)) + L"/44100";
     using namespace ftxui::dom;
     auto document =
-        hbox(text(L"gauge = -"), flex(gauge(percentage)), text(L"-"));
+        hbox(
+          text(L"downloading:"),
+          flex(gauge(percentage)),
+          text(L" " + data_downloaded)
+        );
     auto screen = ftxui::Screen(100, 1);
     Render(screen, document.get());
     std::cout << '\r' << screen.ToString() << std::flush;
diff --git a/examples/menu/CMakeLists.txt b/examples/menu/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..3b5e4200c142ed674867a8d241e502d4af574cb4
--- /dev/null
+++ b/examples/menu/CMakeLists.txt
@@ -0,0 +1,4 @@
+add_executable(menu_main
+  main.cpp
+)
+target_link_libraries(menu_main PRIVATE ftxui)
diff --git a/examples/menu/main.cpp b/examples/menu/main.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..2dd62340ef56ffa6fb94abacb91521613589e892
--- /dev/null
+++ b/examples/menu/main.cpp
@@ -0,0 +1,21 @@
+#include <chrono>
+#include <iostream>
+#include <thread>
+
+#include "ftxui/screen_interactive.hpp"
+#include "ftxui/component/menu.hpp"
+
+int main(int argc, const char *argv[])
+{
+  ftxui::ScreenInteractive screen(30,3);
+  ftxui::component::Menu menu(screen.delegate());
+  menu.entries = {
+    L"entry 1",
+    L"entry 2",
+    L"entry 3"
+  };
+  menu.selected = 0;
+  menu.on_enter = screen.ExitLoopClosure();
+
+  screen.Loop();
+}
diff --git a/examples/menu2/CMakeLists.txt b/examples/menu2/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..719d9bc26059fae9846901522477b327e6c96248
--- /dev/null
+++ b/examples/menu2/CMakeLists.txt
@@ -0,0 +1,4 @@
+add_executable(menu2_main
+  main.cpp
+)
+target_link_libraries(menu2_main PRIVATE ftxui)
diff --git a/examples/menu2/main.cpp b/examples/menu2/main.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..80accafc8bbe7cef74ef44368669eb8a0949107f
--- /dev/null
+++ b/examples/menu2/main.cpp
@@ -0,0 +1,75 @@
+#include <chrono>
+#include <iostream>
+#include <thread>
+
+#include "ftxui/screen_interactive.hpp"
+#include "ftxui/component/menu.hpp"
+#include "ftxui/component/component_horizontal.hpp"
+#include "ftxui/component/component_vertical.hpp"
+#include "ftxui/util/string.hpp"
+
+using namespace ftxui::component;
+using namespace ftxui::dom;
+
+class MyComponent : ComponentHorizontal {
+  public:
+   MyComponent(ftxui::component::Delegate* delegate)
+       : ComponentHorizontal(delegate),
+         left_menu(delegate->NewChild()),
+         right_menu(delegate->NewChild()) {
+     left_menu.entries = {L"0%",  L"10%", L"20%", L"30%", L"40%", L"50%",
+                          L"60%", L"70%", L"80%", L"90%"};
+     right_menu.entries = {L"0%",  L"1%", L"2%", L"3%", L"4%", L"5%",
+                           L"6%", L"7%", L"8%", L"9%", L"10%"};
+
+     left_menu.on_enter = [this]() { on_enter(); };
+     right_menu.on_enter = [this]() { on_enter(); };
+     Focus(&left_menu);
+   }
+
+   std::function<void()> on_enter = [](){};
+  private:
+   Menu left_menu;
+   Menu right_menu;
+
+   Element Render() override {
+     int sum = left_menu.selected * 10 + right_menu.selected;
+     return
+       frame(
+         vbox(
+           // -------- Top panel --------------
+           hbox(
+             // -------- Left Menu --------------
+             flex(
+               vbox(
+                 hcenter(bold(text(L"Percentage by 10%"))),
+                 left_menu.Render()
+               )
+             ),
+             // -------- Right Menu --------------
+             flex(
+               vbox(
+                 hcenter(bold(text(L"Percentage by 1%"))),
+                 right_menu.Render()
+               )
+             ),
+             flex()
+           ),
+           separator(),
+           // -------- Bottom panel --------------
+           flex(vbox(
+             hbox(text(L" gauge : "), gauge(sum/100.0)),
+             hbox(text(L"  text : "), text(to_wstring(std::to_string(sum) + " %")))
+           ))
+         )
+       );
+   }
+};
+
+int main(int argc, const char *argv[])
+{
+  ftxui::ScreenInteractive screen(60,17);
+  MyComponent component(screen.delegate());
+  component.on_enter = screen.ExitLoopClosure();
+  screen.Loop();
+}
diff --git a/examples/print_key_press/CMakeLists.txt b/examples/print_key_press/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..8245f948a4ecbcd183f6fb740c104972e3359af1
--- /dev/null
+++ b/examples/print_key_press/CMakeLists.txt
@@ -0,0 +1,4 @@
+add_executable(print_key_press
+  main.cpp
+)
+target_link_libraries(print_key_press PRIVATE ftxui)
diff --git a/examples/print_key_press/main.cpp b/examples/print_key_press/main.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..b36d28153cc9664812b9011ec09dbf3eed05a9ca
--- /dev/null
+++ b/examples/print_key_press/main.cpp
@@ -0,0 +1,44 @@
+#include <chrono>
+#include <iostream>
+#include <thread>
+
+#include "ftxui/screen_interactive.hpp"
+#include "ftxui/component/component.hpp"
+#include "ftxui/util/string.hpp"
+
+class DrawKey : public ftxui::component::Component {
+ public:
+  DrawKey(ftxui::component::Delegate* delegate)
+      : ftxui::component::Component(delegate) {}
+
+  ftxui::dom::Element Render() override {
+    using namespace ftxui::dom;
+    Children children;
+    for (size_t i = std::max(0, (int)keys.size() - 10); i < keys.size(); ++i) {
+      try {
+        std::string line = std::to_string(i) + " -> " + std::to_string(keys[i]) +
+                           " (" + char(keys[i]) + ")";
+        children.push_back(text(to_wstring(line)));
+      } catch (...) {
+        std::string line = std::to_string(i) + " -> " + std::to_string(keys[i]) +
+                           " (undefined)";
+        children.push_back(text(to_wstring(line)));
+      }
+    }
+    return vbox(std::move(children));
+  }
+
+  bool Event(int key) override {
+    keys.push_back(key);
+    return true;
+  }
+
+ private:
+  std::vector<int> keys;
+};
+
+int main(int argc, const char* argv[]) {
+  ftxui::ScreenInteractive screen(80,10);
+  DrawKey draw_key(screen.delegate());
+  screen.Loop();
+}
diff --git a/examples/separator/main.cpp b/examples/separator/main.cpp
index 0c23f32611b402721692777cba35b63882d318fd..e3426d88718c3e11f9e47ea0d8aa9a59a5e96228 100644
--- a/examples/separator/main.cpp
+++ b/examples/separator/main.cpp
@@ -1,5 +1,5 @@
-#include "ftxui/core/screen.hpp"
-#include "ftxui/core/dom/elements.hpp"
+#include "ftxui/screen.hpp"
+#include "ftxui/dom/elements.hpp"
 #include <iostream>
 
 int main(int argc, const char *argv[])
@@ -15,7 +15,7 @@ int main(int argc, const char *argv[])
         center(text(L"bottom-column"))
       ))
     );
-  auto screen = ftxui::Screen::WholeTerminal();
+  auto screen = ftxui::Screen::TerminalFullscreen();
   Render(screen, document.get());
 
   std::cout << screen.ToString();
diff --git a/examples/toggle/CMakeLists.txt b/examples/toggle/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..a1784e26b949fd0d20202ea16e999b22229fd12c
--- /dev/null
+++ b/examples/toggle/CMakeLists.txt
@@ -0,0 +1,4 @@
+add_executable(toogle_main
+  main.cpp
+)
+target_link_libraries(toogle_main PRIVATE ftxui)
diff --git a/examples/toggle/main.cpp b/examples/toggle/main.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..959cc705ff726ee882849eda3e525d691a10316a
--- /dev/null
+++ b/examples/toggle/main.cpp
@@ -0,0 +1,69 @@
+#include <chrono>
+#include <iostream>
+#include <thread>
+
+#include "ftxui/screen_interactive.hpp"
+#include "ftxui/component/toggle.hpp"
+#include "ftxui/component/component_horizontal.hpp"
+#include "ftxui/component/component_vertical.hpp"
+#include "ftxui/util/string.hpp"
+
+using namespace ftxui::component;
+using namespace ftxui::dom;
+
+class MyComponent : ComponentVertical {
+ public:
+  MyComponent(ftxui::component::Delegate* delegate)
+      : ComponentVertical(delegate),
+        toggle_1(delegate->NewChild()),
+        toggle_2(delegate->NewChild()),
+        toggle_3(delegate->NewChild()) {
+    toggle_1.on = L"On";
+    toggle_1.off = L"Off";
+
+    toggle_2.on = L"Enabled";
+    toggle_2.off = L"Disabled";
+
+    toggle_3.on = L"10€";
+    toggle_3.off = L"0€";
+
+    Focus(&toggle_1);
+  }
+
+  std::function<void()> on_enter = []() {};
+
+ private:
+  Toggle toggle_1;
+  Toggle toggle_2;
+  Toggle toggle_3;
+
+  Element Render() override {
+    return
+      vbox(
+        text(L"Choose your options:"),
+        text(L""),
+        hbox(text(L" * Poweroff on startup      : "), toggle_1.Render()),
+        hbox(text(L" * Out of process           : "), toggle_2.Render()),
+        hbox(text(L" * Price of the information : "), toggle_3.Render())
+      );
+  }
+
+  bool Event(int key) override {
+    if (ComponentVertical::Event(key))
+      return true;
+
+    if (key == 10) {
+      on_enter();
+      return true;
+    }
+
+    return false;
+  }
+};
+
+int main(int argc, const char* argv[]) {
+  ftxui::ScreenInteractive screen(50,5);
+  MyComponent component(screen.delegate());
+  component.on_enter = screen.ExitLoopClosure();
+  screen.Loop();
+}
diff --git a/examples/vbox_hbox/main.cpp b/examples/vbox_hbox/main.cpp
index bae809019d846152e621e285d1f94df86f31997e..f4efb41e42d007fec9cd2a948458adb21b165d50 100644
--- a/examples/vbox_hbox/main.cpp
+++ b/examples/vbox_hbox/main.cpp
@@ -1,5 +1,5 @@
-#include "ftxui/core/screen.hpp"
-#include "ftxui/core/dom/elements.hpp"
+#include "ftxui/screen.hpp"
+#include "ftxui/dom/elements.hpp"
 #include <iostream>
 
 int main(int argc, const char *argv[])
@@ -27,7 +27,7 @@ int main(int argc, const char *argv[])
         text(L"south-east")
       )
     );
-  auto screen = ftxui::Screen::WholeTerminal();
+  auto screen = ftxui::Screen::TerminalFullscreen();
   Render(screen, document.get());
 
   std::cout << screen.ToString();
diff --git a/ftxui/CMakeLists.txt b/ftxui/CMakeLists.txt
index 46a91b581e14a162731f5a5ac67766b6ec44aef0..dc5d1fffa49d79b5c5f107be328a86b8822041ac 100644
--- a/ftxui/CMakeLists.txt
+++ b/ftxui/CMakeLists.txt
@@ -2,23 +2,32 @@ cmake_minimum_required(VERSION 3.0)
 project(ftxui)
 
 add_library(ftxui
-  src/ftxui/core/component.cpp
-  src/ftxui/core/dom/frame.cpp
-  src/ftxui/core/dom/centered.cpp
-  src/ftxui/core/dom/flex.cpp
-  src/ftxui/core/dom/frame.cpp
-  src/ftxui/core/dom/gauge.cpp
-  src/ftxui/core/dom/hbox.cpp
-  src/ftxui/core/dom/node.cpp
-  src/ftxui/core/dom/separator.cpp
-  src/ftxui/core/dom/text.cpp
-  src/ftxui/core/dom/vbox.cpp
-  src/ftxui/core/screen.cpp
-  src/ftxui/core/terminal.cpp
+  src/ftxui/component/component.cpp
+  src/ftxui/component/component_direction.cpp
+  src/ftxui/component/component_horizontal.cpp
+  src/ftxui/component/component_vertical.cpp
+  src/ftxui/component/toggle.cpp
+  src/ftxui/component/menu.cpp
+  src/ftxui/dom/bold.cpp
+  src/ftxui/dom/dim.cpp
+  src/ftxui/dom/underlined.cpp
+  src/ftxui/dom/inverted.cpp
+  src/ftxui/dom/composite_decorator.cpp
+  src/ftxui/dom/flex.cpp
+  src/ftxui/dom/frame.cpp
+  src/ftxui/dom/frame.cpp
+  src/ftxui/dom/gauge.cpp
+  src/ftxui/dom/hbox.cpp
+  src/ftxui/dom/node.cpp
+  src/ftxui/dom/separator.cpp
+  src/ftxui/dom/text.cpp
+  src/ftxui/dom/vbox.cpp
+  src/ftxui/screen.cpp
+  src/ftxui/screen_interactive.cpp
+  src/ftxui/terminal.cpp
   src/ftxui/util/string.cpp
 )
 
-
 target_include_directories(ftxui
   PUBLIC include
   PRIVATE src
@@ -50,8 +59,9 @@ if (GTEST_FOUND AND THREADS_FOUND)
   endfunction(add_new_test)
 
   add_new_test(dom_tests
-    src/ftxui/core/dom/text_test.cpp
-    src/ftxui/core/dom/hbox_test.cpp
-    src/ftxui/core/dom/vbox_test.cpp
+    src/ftxui/dom/gauge_test.cpp
+    src/ftxui/dom/hbox_test.cpp
+    src/ftxui/dom/text_test.cpp
+    src/ftxui/dom/vbox_test.cpp
   )
 endif()
diff --git a/ftxui/include/ftxui/README.md b/ftxui/include/ftxui/README.md
index 5b0dc903ad4dbbc9206dc3b7f31adf153dc0d8dd..74e2a21fe3ade6b126cf663fa75981dc965d634b 100644
--- a/ftxui/include/ftxui/README.md
+++ b/ftxui/include/ftxui/README.md
@@ -1 +1,31 @@
-State => Components => Document => Text.
+# 
+* Level 0: terminal output.
+* Level 1: ftxui::Screen               
+* Level 2: ftxui::dom::Node
+* Level 3: ftxui::component::Component
+
+## Level 0: terminal output.
+  The terminal you know, you can append text on it. It is represented by
+  std::cout.
+
+## Level 1: ftxui::Screen               
+  A rectangular grid of characters.
+  Use Terminal::ToString() to append its content into the console.
+
+## Level 2: ftxui::dom::Node
+  A hierarchical set of element.
+  They handle layout and Render themself on the screen.
+  See ftxui/dom/elements.hpp
+
+  You can make implement your own.
+
+## Level 3: ftxui::component::Component
+  A hierarchical set of component. A component render itself by producing
+  ftxui::dom::Node in Component::Render().
+  
+  Some component can handle events:
+    * keyboard
+    * mouse
+    * terminal event
+
+  You can make implement your own.
diff --git a/ftxui/include/ftxui/core/box.hpp b/ftxui/include/ftxui/box.hpp
similarity index 100%
rename from ftxui/include/ftxui/core/box.hpp
rename to ftxui/include/ftxui/box.hpp
diff --git a/ftxui/include/ftxui/component/Event.hpp b/ftxui/include/ftxui/component/Event.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..4ce8a77c4424b4ca8258e699ccdbcc215ae2a41f
--- /dev/null
+++ b/ftxui/include/ftxui/component/Event.hpp
@@ -0,0 +1,34 @@
+#ifndef FTXUI_COMPONENT_EVENT
+#define FTXUI_COMPONENT_EVENT
+
+namespace ftxui {
+namespace component {
+
+struct Event{
+  // --- Character ---
+  static Event Character(char);
+
+  // --- Arrow ---
+  static Event Arrow_Left;
+  static Event Arrow_Right;
+  static Event Arrow_Up;
+  static Event Arrow_Down;
+  
+  // --- Other ---
+  static Event Backspace;
+  static Event Delete;
+  static Event Escape;
+  static Event F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12;
+
+  // Internal representation.
+  int values [3];
+  Event(int values[3]) : values(values);
+
+};
+
+
+} // namespace component
+} // namespace ftxui
+
+
+#endif /* end of include guard: FTXUI_COMPONENT_EVENT */
diff --git a/ftxui/include/ftxui/component/component.hpp b/ftxui/include/ftxui/component/component.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..80e77b7e869f2a58bf2683f2d333b042a00001bf
--- /dev/null
+++ b/ftxui/include/ftxui/component/component.hpp
@@ -0,0 +1,44 @@
+#ifndef FTXUI_COMPONENT_COMPONENT_HPP
+#define FTXUI_COMPONENT_COMPONENT_HPP
+
+#include "ftxui/dom/elements.hpp"
+#include "ftxui/component/delegate.hpp"
+
+namespace ftxui {
+namespace component {
+
+class Delegate;
+class Focus;
+
+class Component {
+ public:
+  // Constructor/Destructor.
+  Component(Delegate* delegate);
+  virtual ~Component();
+
+  // Render the component.
+  virtual dom::Element Render();
+
+  // Handle an event. By default, it calls this function on each children.
+  virtual bool Event(int key);
+
+  // If this component contains children, this indicates which one is active. It
+  // can be none of them.
+  // We say an element has the focus if the chain of GetActiveChild() from the
+  // root component contains this object.
+  virtual Component* GetActiveChild() { return nullptr; }
+  bool Active(); // True is this component is an active child.
+  bool Focused(); // True if all the ancestors are active childs.
+
+  Component* Parent();
+  Component* PreviousSibling();
+  Component* NextSibling();
+  
+ private:
+  Delegate* delegate_;
+};
+
+}  // namespace component
+}  // namespace ftxui
+
+#endif /* end of include guard: FTXUI_COMPONENT_COMPONENT_HPP */
diff --git a/ftxui/include/ftxui/component/component_direction.hpp b/ftxui/include/ftxui/component/component_direction.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..d71f2ac0e4d96f1199705873c8c046e8e02daa7d
--- /dev/null
+++ b/ftxui/include/ftxui/component/component_direction.hpp
@@ -0,0 +1,25 @@
+#ifndef FTXUI_COMPONENT_COMPONENT_DIRECTION_H_
+#define FTXUI_COMPONENT_COMPONENT_DIRECTION_H_
+
+#include "ftxui/component/component.hpp"
+
+namespace ftxui {
+namespace component {
+
+// A component where focus and events are automatically handled for you.
+class ComponentDirection : public Component {
+ public:
+  ComponentDirection(Delegate* delegate);
+  bool Event(int key) override;
+  Component* GetActiveChild() override;
+
+ protected:
+  void Focus(Component* child);
+  virtual bool HandleDirection(int key) = 0;
+  Component* active_child_;
+};
+
+} // namespace component
+} // namespace ftxui
+
+#endif /* end of include guard: FTXUI_COMPONENT_COMPONENT_DIRECTION_H_ */
diff --git a/ftxui/include/ftxui/component/component_horizontal.hpp b/ftxui/include/ftxui/component/component_horizontal.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..f518c328b3c124404a1aa22532d1989b27473b85
--- /dev/null
+++ b/ftxui/include/ftxui/component/component_horizontal.hpp
@@ -0,0 +1,20 @@
+#ifndef FTXUI_COMPONENT_COMPONENT_HORIZONTAL_H_
+#define FTXUI_COMPONENT_COMPONENT_HORIZONTAL_H_
+
+#include "ftxui/component/component_direction.hpp"
+
+namespace ftxui {
+namespace component {
+
+// A component where focus and events are automatically handled for you.
+// It assumes its children are put in the horizontal direction.
+class ComponentHorizontal : public ComponentDirection {
+ public:
+  ComponentHorizontal(Delegate* delegate);
+  bool HandleDirection(int key) override;
+};
+
+} // namespace component
+} // namespace ftxui
+
+#endif /* end of include guard: FTXUI_COMPONENT_COMPONENT_HORIZONTAL_H_ */
diff --git a/ftxui/include/ftxui/component/component_vertical.hpp b/ftxui/include/ftxui/component/component_vertical.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..a8408589c602c61c9e030368e857a9ca176a77d1
--- /dev/null
+++ b/ftxui/include/ftxui/component/component_vertical.hpp
@@ -0,0 +1,20 @@
+#ifndef FTXUI_COMPONENT_COMPONENT_VERTICAL_H_
+#define FTXUI_COMPONENT_COMPONENT_VERTICAL_H_
+
+#include "ftxui/component/component_direction.hpp"
+
+namespace ftxui {
+namespace component {
+
+// A component where focus and events are automatically handled for you.
+// It assumes its children are put in the vertical direction.
+class ComponentVertical : public ComponentDirection {
+ public:
+  ComponentVertical(Delegate* delegate);
+  bool HandleDirection(int key) override;
+};
+
+} // namespace component
+} // namespace ftxui
+
+#endif /* end of include guard: FTXUI_COMPONENT_COMPONENT_VERTICAL_H_ */
diff --git a/ftxui/include/ftxui/component/delegate.hpp b/ftxui/include/ftxui/component/delegate.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..d4bc236b7e577688cd7dad1144f6a9a60100ac32
--- /dev/null
+++ b/ftxui/include/ftxui/component/delegate.hpp
@@ -0,0 +1,34 @@
+#ifndef FTXUI_COMPONENT_DELEGATE_HPP
+#define FTXUI_COMPONENT_DELEGATE_HPP
+
+#include "ftxui/dom/elements.hpp"
+
+namespace ftxui {
+namespace component {
+
+class Component;
+
+class Delegate {
+ public:
+  Delegate() {}
+  virtual ~Delegate() {}
+
+  // A Delegate shadows a component.
+  virtual void Register(Component* component) = 0;
+  virtual Component* component() = 0;
+
+  // Create new children.
+  virtual Delegate* NewChild() = 0;
+  virtual std::vector<Delegate*> children() = 0;
+
+  // Navigate in the tree.
+  virtual Delegate* PreviousSibling() = 0;
+  virtual Delegate* NextSibling() = 0;
+  virtual Delegate* Parent() = 0;
+  virtual Delegate* Root() = 0;
+};
+
+}  // namespace component
+}  // namespace ftxui
+
+#endif /* end of include guard: FTXUI_COMPONENT_DELEGATE_HPP */
diff --git a/ftxui/include/ftxui/component/menu.hpp b/ftxui/include/ftxui/component/menu.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..79dd19f984df6dcfce17bd6df5d6b4f2b01a761b
--- /dev/null
+++ b/ftxui/include/ftxui/component/menu.hpp
@@ -0,0 +1,31 @@
+#ifndef FTXUI_COMPONENT_MENU
+#define FTXUI_COMPONENT_MENU
+
+#include "ftxui/component/component.hpp"
+#include <functional>
+
+namespace ftxui {
+namespace component {
+
+class Menu : public Component {
+ public:
+  // Constructor.
+  Menu(Delegate*);
+
+  // State.
+  std::vector<std::wstring> entries = {};
+  int selected = 0;
+
+  // State update callback.
+  std::function<void()> on_change = [](){};
+  std::function<void()> on_enter = [](){};
+
+  // Component implementation.
+  dom::Element Render() override;
+	bool Event(int key) override;
+};
+
+}  // namespace component
+}  // namespace ftxui
+
+#endif /* end of include guard: FTXUI_COMPONENT_MENU */
diff --git a/ftxui/include/ftxui/component/toggle.hpp b/ftxui/include/ftxui/component/toggle.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..daa18e74fb7bb83d5504fb2246ef0d7523a8b86c
--- /dev/null
+++ b/ftxui/include/ftxui/component/toggle.hpp
@@ -0,0 +1,31 @@
+#ifndef FTXUI_COMPONENT_TOGGLE_H_
+#define FTXUI_COMPONENT_TOGGLE_H_
+
+#include "ftxui/component/component.hpp"
+#include <functional>
+
+namespace ftxui {
+namespace component {
+
+class Toggle : public Component {
+ public:
+  // Constructor.
+  Toggle(Delegate*);
+
+  // State.
+  bool activated = true;
+  std::wstring on = L"On";
+  std::wstring off = L"Off";
+
+  // Callback.
+  std::function<void()> on_change = [](){};
+
+  // Component implementation.
+  dom::Element Render() override;
+	bool Event(int key) override;
+};
+
+}  // namespace component
+}  // namespace ftxui
+
+#endif /* end of include guard: FTXUI_COMPONENT_TOGGLE_H_ */
diff --git a/ftxui/include/ftxui/core/component.hpp b/ftxui/include/ftxui/core/component.hpp
deleted file mode 100644
index fb0c4f00f19f4f2e1ec354609ee6691735f51beb..0000000000000000000000000000000000000000
--- a/ftxui/include/ftxui/core/component.hpp
+++ /dev/null
@@ -1,23 +0,0 @@
-#ifndef FTXUI_STATE_HPP
-#define FTXUI_STATE_HPP
-
-#include "ftxui/core/requirement.hpp"
-#include "ftxui/core/document.hpp"
-
-namespace ftxui {
-
-class Component {
- public:
-  virtual Document Render() = 0;
-
-  // Requirement -------------------------------------------------------------
-  virtual void ComputeRequirement();
-  Requirement requirement() { return requirement_; }
-
- private:
-  Requirement requirement_;
-};
-
-};  // namespace ftxui
-
-#endif /* end of include guard: FTXUI_STATE_HPP */
diff --git a/ftxui/include/ftxui/core/document.hpp b/ftxui/include/ftxui/core/document.hpp
deleted file mode 100644
index 51034f91738ed2509984f4d410e9834b850530fc..0000000000000000000000000000000000000000
--- a/ftxui/include/ftxui/core/document.hpp
+++ /dev/null
@@ -1,12 +0,0 @@
-#ifndef FTXUI_DOCUMENT_HPP
-#define FTXUI_DOCUMENT_HPP
-
-namespace ftxui {
-
-class Document {
-   
-};
-
-};
-
-#endif /* end of include guard: FTXUI_DOCUMENT_HPP */
diff --git a/ftxui/include/ftxui/core/screen.hpp b/ftxui/include/ftxui/core/screen.hpp
deleted file mode 100644
index 9d676010d4d00511b55713836dedc5b0193b9789..0000000000000000000000000000000000000000
--- a/ftxui/include/ftxui/core/screen.hpp
+++ /dev/null
@@ -1,33 +0,0 @@
-#ifndef FTXUI_CORE_SCREEN
-#define FTXUI_CORE_SCREEN
-
-#include <string>
-#include <vector>
-#include <memory>
-
-namespace ftxui {
-namespace dom {
-  class Node;
-}
-
-class Screen {
- public:
-  Screen(size_t dimx, size_t dimy);
-  wchar_t& at(size_t x, size_t y);
-  std::string ToString();
-
-  size_t dimx() { return dimx_;}
-  size_t dimy() { return dimy_;}
-
-  static Screen WholeTerminal();
-  static Screen TerminalOutput(std::unique_ptr<dom::Node>& element);
-
- private:
-  size_t dimx_;
-  size_t dimy_;
-  std::vector<std::wstring> lines_;
-};
-
-};  // namespace ftxui
-
-#endif /* end of include guard: FTXUI_CORE_SCREEN */
diff --git a/ftxui/include/ftxui/core/dom/elements.hpp b/ftxui/include/ftxui/dom/elements.hpp
similarity index 61%
rename from ftxui/include/ftxui/core/dom/elements.hpp
rename to ftxui/include/ftxui/dom/elements.hpp
index df2f7cc890c6bc607105421092feeb5b15e6bbcb..40c2dfe2d5529bb6979ed3a60b1420514fcd8545 100644
--- a/ftxui/include/ftxui/core/dom/elements.hpp
+++ b/ftxui/include/ftxui/dom/elements.hpp
@@ -1,16 +1,14 @@
-#ifndef FTXUI_CORE_DOM_ELEMENTS_HPP
-#define FTXUI_CORE_DOM_ELEMENTS_HPP
+#ifndef FTXUI_DOM_ELEMENTS_HPP
+#define FTXUI_DOM_ELEMENTS_HPP
 
-#include "ftxui/core/dom/node.hpp"
-#include <initializer_list>
+#include "ftxui/dom/node.hpp"
 
 namespace ftxui {
 namespace dom {
 
 using Element = std::unique_ptr<Node>;
 using Child = std::unique_ptr<Node>;
-using Children = std::vector<std::unique_ptr<Node>>;
-
+using Children = std::vector<Child>;
 
 // --- Layout ----
 Element vbox(Children);
@@ -22,7 +20,13 @@ Element text(std::wstring text);
 Element separator();
 Element gauge(float ratio);
 Element frame(Child);
-Element frame(std::wstring title, Child);
+Element frame(Child title, Child content);
+
+// -- Decorator (Style) ---
+Element bold(Element);
+Element dim(Element);
+Element inverted(Element);
+Element underlined(Element);
 
 // --- Decorator ---
 Element hcenter(Element);
@@ -31,23 +35,23 @@ Element center(Element);
 Element flex(Element);
 
 template <class... Args>
-std::vector<Element> unpack(Args... args) {
-  std::vector<Element> vec;
+Children unpack(Args... args) {
+  Children vec;
   (vec.push_back(std::forward<Args>(args)), ...);
   return vec;
 }
 
 template <class... Args>
-std::unique_ptr<Node> vbox(Args... children) {
+Element vbox(Args... children) {
   return vbox(unpack(std::forward<Args>(children)...));
 }
 
 template <class... Args>
-std::unique_ptr<Node> hbox(Args... children) {
+Element hbox(Args... children) {
   return hbox(unpack(std::forward<Args>(children)...));
 }
 
 };  // namespace dom
 };  // namespace ftxui
 
-#endif /* end of include guard: FTXUI_CORE_DOM_ELEMENTS_HPP */
+#endif /* end of include guard: FTXUI_DOM_ELEMENTS_HPP */
diff --git a/ftxui/include/ftxui/core/dom/node.hpp b/ftxui/include/ftxui/dom/node.hpp
similarity index 79%
rename from ftxui/include/ftxui/core/dom/node.hpp
rename to ftxui/include/ftxui/dom/node.hpp
index f843228a9daad8c78e8444fb4ecd97c12680c9e7..6a5f7beb5334f2f9289f282268de65369dcd78ed 100644
--- a/ftxui/include/ftxui/core/dom/node.hpp
+++ b/ftxui/include/ftxui/dom/node.hpp
@@ -1,12 +1,12 @@
-#ifndef CORE_DOM_NODE_HPP
-#define CORE_DOM_NODE_HPP
+#ifndef DOM_NODE_HPP
+#define DOM_NODE_HPP
 
 #include <memory>
 #include <vector>
 
-#include "ftxui/core/requirement.hpp"
-#include "ftxui/core/screen.hpp"
-#include "ftxui/core/box.hpp"
+#include "ftxui/requirement.hpp"
+#include "ftxui/screen.hpp"
+#include "ftxui/box.hpp"
 
 namespace ftxui {
 namespace dom {
@@ -41,4 +41,4 @@ void Render(Screen& screen, Node* node);
 };  // namespace dom
 };  // namespace ftxui
 
-#endif /* end of include guard: CORE_DOM_NODE_HPP */
+#endif /* end of include guard: DOM_NODE_HPP */
diff --git a/ftxui/include/ftxui/core/requirement.hpp b/ftxui/include/ftxui/requirement.hpp
similarity index 67%
rename from ftxui/include/ftxui/core/requirement.hpp
rename to ftxui/include/ftxui/requirement.hpp
index 74089b46cbb49da95f79a536cb37caf674089dbe..2b4e714a22174716fcb06bc6fcdace7d690fb398 100644
--- a/ftxui/include/ftxui/core/requirement.hpp
+++ b/ftxui/include/ftxui/requirement.hpp
@@ -1,5 +1,5 @@
-#ifndef FTXUI_LAYOUT_REQUIREMENT_HPP
-#define FTXUI_LAYOUT_REQUIREMENT_HPP
+#ifndef FTXUI_REQUIREMENT_HPP
+#define FTXUI_REQUIREMENT_HPP
 
 namespace ftxui {
 
@@ -25,4 +25,4 @@ struct Requirement {
 
 };  // namespace ftxui
 
-#endif /* end of include guard: FTXUI_LAYOUT_REQUIREMENT_HPP */
+#endif /* end of include guard: FTXUI_REQUIREMENT_HPP */
diff --git a/ftxui/include/ftxui/screen.hpp b/ftxui/include/ftxui/screen.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..2782271ac461ec263b775863f5cebb76f4438615
--- /dev/null
+++ b/ftxui/include/ftxui/screen.hpp
@@ -0,0 +1,55 @@
+#ifndef FTXUI_SCREEN
+#define FTXUI_SCREEN
+
+#include <string>
+#include <vector>
+#include <memory>
+
+namespace ftxui {
+namespace dom {
+  class Node;
+}
+
+struct Pixel {
+  wchar_t character = U' ';
+  bool bold = false;
+  bool inverted = false;
+  bool underlined = false;
+  bool dim = false;
+};
+
+class Screen {
+ public:
+  // Constructor.
+  Screen(size_t dimx, size_t dimy);
+
+  // Constructor using the terminal.
+  static Screen TerminalFullscreen();
+  static Screen TerminalOutput(std::unique_ptr<dom::Node>& element);
+
+  // dom::Node write into the screen using Screen::at.
+  wchar_t& at(size_t x, size_t y);
+  Pixel& PixelAt(size_t x, size_t y);
+
+  // Convert the screen into a printable string in the terminal.
+  std::string ToString();
+
+  // Get screen dimensions.
+  size_t dimx() { return dimx_;}
+  size_t dimy() { return dimy_;}
+
+  // Move the terminal cursor n-lines up with n = dimy().
+  std::string ResetPosition();
+
+  // Fill with space.
+  void Clear();
+
+ private:
+  size_t dimx_;
+  size_t dimy_;
+  std::vector<std::vector<Pixel>> pixels_;
+};
+
+};  // namespace ftxui
+
+#endif /* end of include guard: FTXUI_SCREEN */
diff --git a/ftxui/include/ftxui/screen_interactive.hpp b/ftxui/include/ftxui/screen_interactive.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..1acf9e1a949efcfade4e72ca089e4d20499ba5c1
--- /dev/null
+++ b/ftxui/include/ftxui/screen_interactive.hpp
@@ -0,0 +1,34 @@
+#ifndef FTXUI_SCREEN_INTERACTIVE
+#define FTXUI_SCREEN_INTERACTIVE
+
+#include "ftxui/screen.hpp"
+#include <functional>
+#include <memory>
+
+namespace ftxui {
+
+namespace component {
+  class Delegate;
+  class Component;
+} // namespace component
+
+class ScreenInteractive : public Screen {
+  public:
+    ScreenInteractive(size_t dimx, size_t dimy);
+    ~ScreenInteractive();
+    component::Delegate* delegate();
+    void Loop();
+		std::function<void()> ExitLoopClosure();
+
+  private:
+   class Delegate;
+   std::unique_ptr<Delegate> delegate_;
+
+	 void Clear();
+	 void Draw();
+	 bool quit_ = false;
+};
+
+}  // namespace ftxui
+
+#endif /* end of include guard: FTXUI_SCREEN_INTERACTIVE */
diff --git a/ftxui/src/ftxui/component/component.cpp b/ftxui/src/ftxui/component/component.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..369e9c34ea63d861e81397dc568f3f104505a56c
--- /dev/null
+++ b/ftxui/src/ftxui/component/component.cpp
@@ -0,0 +1,59 @@
+#include "ftxui/component/component.hpp"
+#include "ftxui/component/delegate.hpp"
+#include <assert.h>
+
+namespace ftxui {
+namespace component {
+
+Component::Component(Delegate* delegate) {
+  delegate_ = delegate;
+  delegate_->Register(this);
+}
+
+Component::~Component() {}
+
+dom::Element Component::Render() {
+  using namespace ftxui::dom;
+  return text(L"Not implemented component");
+}
+
+bool Component::Event(int key) {
+  return false;
+}
+
+bool Component::Focused() {
+  Delegate* current = delegate_->Root();
+  while (current) {
+    if (current == delegate_)
+      return true;
+
+    Component* active_child = current->component()->GetActiveChild();
+    current = active_child ? active_child->delegate_ : nullptr;
+  }
+  return false;
+}
+
+bool Component::Active() {
+  Delegate* parent = delegate_->Parent();
+  return parent && parent->component()->GetActiveChild() == this;
+}
+
+Component* Component::PreviousSibling() {
+  Delegate* sibling = delegate_->PreviousSibling();
+  return sibling ? sibling->component() : nullptr;
+}
+
+Component* Component::NextSibling() {
+  Delegate* sibling = delegate_->NextSibling();
+  return sibling ? sibling->component() : nullptr;
+}
+
+Component* Component::Parent() {
+  Delegate* parent_delegate = delegate_->Parent();
+  if (!parent_delegate)
+    return nullptr;
+  return parent_delegate->component();
+}
+
+}  // namespace component
+}  // namespace ftxui
diff --git a/ftxui/src/ftxui/component/component_direction.cpp b/ftxui/src/ftxui/component/component_direction.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..fa77b813c05d59d4d94eb7ebb8eb7e48b9e78c1a
--- /dev/null
+++ b/ftxui/src/ftxui/component/component_direction.cpp
@@ -0,0 +1,31 @@
+#include "ftxui/component/component_direction.hpp"
+
+namespace ftxui {
+namespace component {
+
+ComponentDirection::ComponentDirection(Delegate* delegate)
+    : Component(delegate), active_child_(nullptr) {}
+
+bool ComponentDirection::Event(int key) {
+  if (!Focused())
+    return false;
+
+  if (!active_child_)
+    return false;
+
+  if (active_child_->Event(key))
+    return true;
+
+  return HandleDirection(key);
+}
+
+Component* ComponentDirection::GetActiveChild() {
+  return active_child_;
+}
+
+void ComponentDirection::Focus(Component* child) {
+  active_child_ = child;
+}
+
+} // namespace component
+} // namespace ftxui
diff --git a/ftxui/src/ftxui/component/component_horizontal.cpp b/ftxui/src/ftxui/component/component_horizontal.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..012098acf2628437138a9642e1a4d5dda6caa9ea
--- /dev/null
+++ b/ftxui/src/ftxui/component/component_horizontal.cpp
@@ -0,0 +1,32 @@
+#include "ftxui/component/component_horizontal.hpp"
+
+namespace ftxui {
+namespace component {
+
+ComponentHorizontal::ComponentHorizontal(Delegate* delegate)
+    : ComponentDirection(delegate) {}
+
+bool ComponentHorizontal::HandleDirection(int key) {
+  // Left pressed ?
+  if (key == 68 || key == 'h') {
+    Component* previous_sibling = active_child_->PreviousSibling();
+    if (previous_sibling) {
+      active_child_ = previous_sibling;
+      return true;
+    }
+  }
+
+  // Left pressed ?
+  if (key == 67 || key == 'l') {
+    Component* next_sibling = active_child_->NextSibling();
+    if (next_sibling) {
+      active_child_ = next_sibling;
+      return true;
+    }
+  }
+
+  return false;
+}
+
+}  // namespace component
+}  // namespace ftxui
diff --git a/ftxui/src/ftxui/component/component_vertical.cpp b/ftxui/src/ftxui/component/component_vertical.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..70d516e760517d17327c8ca8623daabb51bcc0fd
--- /dev/null
+++ b/ftxui/src/ftxui/component/component_vertical.cpp
@@ -0,0 +1,32 @@
+#include "ftxui/component/component_vertical.hpp"
+
+namespace ftxui {
+namespace component {
+
+ComponentVertical::ComponentVertical(Delegate* delegate)
+    : ComponentDirection(delegate) {}
+
+bool ComponentVertical::HandleDirection(int key) {
+  // Up pressed ?
+  if (key == 65 || key == 'k') {
+    Component* previous_sibling = active_child_->PreviousSibling();
+    if (previous_sibling) {
+      active_child_ = previous_sibling;
+      return true;
+    }
+  }
+
+  // Down pressed ?
+  if (key == 66 || key == 'j') {
+    Component* next_sibling = active_child_->NextSibling();
+    if (next_sibling) {
+      active_child_ = next_sibling;
+      return true;
+    }
+  }
+
+  return false;
+}
+
+}  // namespace component
+}  // namespace ftxui
diff --git a/ftxui/src/ftxui/component/menu.cpp b/ftxui/src/ftxui/component/menu.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..3d5f259ef82237729c2d8f607368b56d30f4df92
--- /dev/null
+++ b/ftxui/src/ftxui/component/menu.cpp
@@ -0,0 +1,53 @@
+#include "ftxui/component/menu.hpp"
+#include <algorithm>
+
+namespace ftxui {
+namespace component {
+
+Menu::Menu(Delegate* delegate) : Component(delegate) {}
+
+dom::Element Menu::Render() {
+  using namespace dom;
+  std::vector<Element> elements;
+  bool focused = Focused();
+  for (size_t i = 0; i < entries.size(); ++i) {
+    if (size_t(selected) == i) {
+      if (focused)
+        elements.push_back(inverted(text(L"> " + entries[i])));
+      else
+        elements.push_back(bold(text(L"> " + entries[i])));
+    }
+    else {
+      elements.push_back(text(L"  " + entries[i]));
+    }
+  }
+  return vbox(std::move(elements));
+}
+
+bool Menu::Event(int key) {
+  if (!Focused())
+    return false;
+
+  int new_selected = selected;
+  if (key == 65 || key == 'k')
+    new_selected--;
+  if (key == 66 || key == 'j')
+    new_selected++;
+  new_selected = std::max(0, std::min(int(entries.size())-1, new_selected));
+
+  if (selected != new_selected) {
+    selected = new_selected;
+    on_change();
+    return true;
+  }
+
+  if (key == 10) {
+    on_enter();
+    return true;
+  }
+
+  return false;
+}
+
+}  // namespace component
+}  // namespace ftxui
diff --git a/ftxui/src/ftxui/component/toggle.cpp b/ftxui/src/ftxui/component/toggle.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..023ca0ee6c07796df8e8b3c2779eb7137a775a63
--- /dev/null
+++ b/ftxui/src/ftxui/component/toggle.cpp
@@ -0,0 +1,47 @@
+#include "ftxui/component/toggle.hpp"
+
+namespace ftxui {
+namespace component {
+
+Toggle::Toggle(Delegate* delegate) : Component(delegate) {}
+
+dom::Element Toggle::Render() {
+  using namespace dom;
+  auto highlight = Focused() ? inverted : bold;
+
+  Children children;
+  children.push_back(text(L"["));
+  if (activated) {
+    children.push_back(highlight(text(on)));
+    children.push_back(text(L"|"));
+    children.push_back(dim(text(off)));
+  } else {
+    children.push_back(dim(text(on)));
+    children.push_back(text(L"|"));
+    children.push_back(highlight(text(off)));
+  }
+  children.push_back(text(L"]"));
+  return hbox(std::move(children));
+}
+
+bool Toggle::Event(int key) {
+
+  if (activated) {
+    if (key == 67 || key == 'l') {
+      activated = false;
+      on_change();
+      return true;
+    }
+  } else {
+    if (key == 68 || key == 'h') {
+      activated = true;
+      on_change();
+      return true;
+    }
+  }
+
+  return false;
+}
+
+}  // namespace component
+}  // namespace ftxui
diff --git a/ftxui/src/ftxui/core/component.cpp b/ftxui/src/ftxui/core/component.cpp
deleted file mode 100644
index cd28bc84672c6c761d316bbd8bde12a8649e9eb5..0000000000000000000000000000000000000000
--- a/ftxui/src/ftxui/core/component.cpp
+++ /dev/null
@@ -1,5 +0,0 @@
-#include "ftxui/core/component.hpp"
-
-namespace ftxui {
-  void Component::ComputeRequirement() {}
-} // namespace ftxui.
diff --git a/ftxui/src/ftxui/core/dom/frame.cpp b/ftxui/src/ftxui/core/dom/frame.cpp
deleted file mode 100644
index 4b43f58ad586ef21ef67667c26e35126538e5232..0000000000000000000000000000000000000000
--- a/ftxui/src/ftxui/core/dom/frame.cpp
+++ /dev/null
@@ -1,57 +0,0 @@
-#include "ftxui/core/dom/node.hpp"
-#include "ftxui/core/dom/elements.hpp"
-
-namespace ftxui {
-namespace dom {
-
-static wchar_t charset[] = L"┌┐└┘─│";
-
-class Frame : public Node {
- public:
-  Frame(Child child) : Node(unpack(std::move(child))) {}
-  ~Frame() override {}
-
-  void ComputeRequirement() override {
-    children[0]->ComputeRequirement();
-    requirement_ = children[0]->requirement();
-    requirement_.min.x += 2;
-    requirement_.min.y += 2;
-  }
-
-  void SetBox(Box box) override {
-    Node::SetBox(box);
-    box.left++;
-    box.right--;
-    box.top++;
-    box.bottom--;
-    children[0]->SetBox(box);
-  }
-
-  void Render(Screen& screen) override {
-    if (box_.left >= box_.right || box_.top >= box_.bottom)
-      return;
-
-    screen.at(box_.left, box_.top) = charset[0];
-    screen.at(box_.right, box_.top) = charset[1];
-    screen.at(box_.left, box_.bottom) = charset[2];
-    screen.at(box_.right, box_.bottom) = charset[3];
-    for(float x = box_.left + 1; x<box_.right; ++x) {
-      screen.at(x, box_.top) = charset[4];
-      screen.at(x, box_.bottom) = charset[4];
-    }
-    for(float y = box_.top + 1; y<box_.bottom; ++y) {
-      screen.at(box_.left, y) = charset[5];
-      screen.at(box_.right,y) = charset[5];
-    }
-    children[0]->Render(screen);
-  }
- private:
-  float progress_;
-};
-
-std::unique_ptr<Node> frame(Child child) {
-  return std::make_unique<Frame>(std::move(child));
-}
-
-};  // namespace dom
-};  // namespace ftxui
diff --git a/ftxui/src/ftxui/core/screen.cpp b/ftxui/src/ftxui/core/screen.cpp
deleted file mode 100644
index 768e17e8155ba21b1b2a3e66fd1fefdde67e6284..0000000000000000000000000000000000000000
--- a/ftxui/src/ftxui/core/screen.cpp
+++ /dev/null
@@ -1,38 +0,0 @@
-#include "ftxui/core/screen.hpp"
-#include "ftxui/core/terminal.hpp"
-#include "ftxui/util/string.hpp"
-#include "ftxui/core/dom/node.hpp"
-
-#include <sstream>
-
-namespace ftxui {
-
-Screen::Screen(size_t dimx, size_t dimy)
-    : dimx_(dimx), dimy_(dimy), lines_(dimy, std::wstring(dimx, U' ')) {}
-
-std::string Screen::ToString() {
-  std::stringstream ss;
-  for (size_t y = 0; y < dimy_; ++y) {
-    ss << to_string(lines_[y]);
-    if (y + 1 < dimy_)
-      ss << '\n';
-  }
-  return ss.str();
-}
-
-wchar_t& Screen::at(size_t x, size_t y) {
-  return lines_[y][x];
-}
-
-Screen Screen::WholeTerminal() {
-  Terminal::Dimensions size = Terminal::Size();
-  return Screen(size.dimx, size.dimy);
-}
-
-Screen Screen::TerminalOutput(std::unique_ptr<dom::Node>& element) {
-  element->ComputeRequirement();
-  Terminal::Dimensions size = Terminal::Size();
-  return Screen(size.dimx, element->requirement().min.y);
-}
-
-};  // namespace ftxui
diff --git a/ftxui/src/ftxui/dom/bold.cpp b/ftxui/src/ftxui/dom/bold.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..cee8d9726a8f0b61d2f317d52b8a745f163e150d
--- /dev/null
+++ b/ftxui/src/ftxui/dom/bold.cpp
@@ -0,0 +1,37 @@
+#include "ftxui/dom/node.hpp"
+#include "ftxui/dom/elements.hpp"
+
+namespace ftxui {
+namespace dom {
+
+class Bold : public Node {
+ public:
+  Bold(Children children) : Node(std::move(children)) {}
+  ~Bold() override {}
+
+  void ComputeRequirement() override {
+    Node::ComputeRequirement();
+    requirement_ = children[0]->requirement();
+  }
+
+  void SetBox(Box box) override {
+    Node::SetBox(box);
+    children[0]->SetBox(box);
+  }
+
+  void Render(Screen& screen) override {
+    Node::Render(screen);
+    for (int y = box_.top; y <= box_.bottom; ++y) {
+      for (int x = box_.left; x <= box_.right; ++x) {
+        screen.PixelAt(x,y).bold = true; 
+      }
+    }
+  }
+};
+
+std::unique_ptr<Node> bold(Child child) {
+  return std::make_unique<Bold>(unpack(std::move(child)));
+}
+
+};  // namespace dom
+};  // namespace ftxui
diff --git a/ftxui/src/ftxui/core/dom/centered.cpp b/ftxui/src/ftxui/dom/composite_decorator.cpp
similarity index 83%
rename from ftxui/src/ftxui/core/dom/centered.cpp
rename to ftxui/src/ftxui/dom/composite_decorator.cpp
index 254c573896fe1bbe9e0d50345177b043924b3636..cedc328136a736a21abb3db9d8bda09b60e7837c 100644
--- a/ftxui/src/ftxui/core/dom/centered.cpp
+++ b/ftxui/src/ftxui/dom/composite_decorator.cpp
@@ -1,5 +1,5 @@
-#include "ftxui/core/dom/node.hpp"
-#include "ftxui/core/dom/elements.hpp"
+#include "ftxui/dom/node.hpp"
+#include "ftxui/dom/elements.hpp"
 
 namespace ftxui {
 namespace dom {
diff --git a/ftxui/src/ftxui/dom/dim.cpp b/ftxui/src/ftxui/dom/dim.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..08283f96d4d658738a801c9272f2a301b532cf7b
--- /dev/null
+++ b/ftxui/src/ftxui/dom/dim.cpp
@@ -0,0 +1,37 @@
+#include "ftxui/dom/node.hpp"
+#include "ftxui/dom/elements.hpp"
+
+namespace ftxui {
+namespace dom {
+
+class Dim : public Node {
+ public:
+  Dim(Children children) : Node(std::move(children)) {}
+  ~Dim() override {}
+
+  void ComputeRequirement() override {
+    Node::ComputeRequirement();
+    requirement_ = children[0]->requirement();
+  }
+
+  void SetBox(Box box) override {
+    Node::SetBox(box);
+    children[0]->SetBox(box);
+  }
+
+  void Render(Screen& screen) override {
+    Node::Render(screen);
+    for (int y = box_.top; y <= box_.bottom; ++y) {
+      for (int x = box_.left; x <= box_.right; ++x) {
+        screen.PixelAt(x,y).dim = true; 
+      }
+    }
+  }
+};
+
+std::unique_ptr<Node> dim(Child child) {
+  return std::make_unique<Dim>(unpack(std::move(child)));
+}
+
+};  // namespace dom
+};  // namespace ftxui
diff --git a/ftxui/src/ftxui/core/dom/flex.cpp b/ftxui/src/ftxui/dom/flex.cpp
similarity index 91%
rename from ftxui/src/ftxui/core/dom/flex.cpp
rename to ftxui/src/ftxui/dom/flex.cpp
index 99afa61098c526cb27f550cfad8adf3bb09a9e4f..9684dff72718a314aade2cff48fdc15076e56f44 100644
--- a/ftxui/src/ftxui/core/dom/flex.cpp
+++ b/ftxui/src/ftxui/dom/flex.cpp
@@ -1,5 +1,5 @@
-#include "ftxui/core/dom/node.hpp"
-#include "ftxui/core/dom/elements.hpp"
+#include "ftxui/dom/node.hpp"
+#include "ftxui/dom/elements.hpp"
 
 namespace ftxui {
 namespace dom {
diff --git a/ftxui/src/ftxui/dom/frame.cpp b/ftxui/src/ftxui/dom/frame.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..6112b701ed9d15176e168c44b1d5eb0600219826
--- /dev/null
+++ b/ftxui/src/ftxui/dom/frame.cpp
@@ -0,0 +1,92 @@
+#include "ftxui/dom/node.hpp"
+#include "ftxui/dom/elements.hpp"
+
+namespace ftxui {
+namespace dom {
+
+static wchar_t charset[] = L"┌┐└┘─│┬┴┤├";
+
+class Frame : public Node {
+ public:
+  Frame(Children children) : Node(std::move(children)) {}
+  ~Frame() override {}
+
+  void ComputeRequirement() override {
+    Node::ComputeRequirement();
+    requirement_ = children[0]->requirement();
+    requirement_.min.x += 2;
+    requirement_.min.y += 2;
+    if (children.size() == 2) {
+      requirement_.min.x =
+          std::max(requirement_.min.x, children[1]->requirement().min.x + 2);
+    }
+  }
+
+  void SetBox(Box box) override {
+    Node::SetBox(box);
+    if (children.size() == 2) {
+      Box title_box;
+      title_box.left = box.left + 1;
+      title_box.right = box.right - 1;
+      title_box.top = box.top;
+      title_box.bottom = box.top;
+      children[1]->SetBox(title_box);
+    }
+    box.left++;
+    box.right--;
+    box.top++;
+    box.bottom--;
+    children[0]->SetBox(box);
+  }
+
+  void Render(Screen& screen) override {
+    // Draw content.
+    children[0]->Render(screen);
+
+    // Draw the frame.
+    if (box_.left >= box_.right || box_.top >= box_.bottom)
+      return;
+
+    screen.at(box_.left, box_.top) = charset[0];
+    screen.at(box_.right, box_.top) = charset[1];
+    screen.at(box_.left, box_.bottom) = charset[2];
+    screen.at(box_.right, box_.bottom) = charset[3];
+    for(float x = box_.left + 1; x<box_.right; ++x) {
+      screen.at(x, box_.top) = charset[4];
+      screen.at(x, box_.bottom) = charset[4];
+    }
+    for(float y = box_.top + 1; y<box_.bottom; ++y) {
+      screen.at(box_.left, y) = charset[5];
+      screen.at(box_.right,y) = charset[5];
+    }
+
+    // Try to merge with separator.
+    for(float x = box_.left + 1; x<box_.right; ++x) {
+      if (screen.at(x, box_.top + 1) == charset[5])
+        screen.at(x, box_.top) = charset[6];
+      if (screen.at(x, box_.bottom - 1) == charset[5])
+        screen.at(x, box_.bottom) = charset[7];
+    }
+    for(float y = box_.top + 1; y<box_.bottom; ++y) {
+      if (screen.at(box_.left+1, y) == charset[4])
+        screen.at(box_.left, y) = charset[9];
+      if (screen.at(box_.right-1, y) == charset[4])
+        screen.at(box_.right,y) = charset[8];
+    }
+
+    // Draw title.
+    if (children.size() == 2)
+      children[1]->Render(screen);
+  }
+};
+
+std::unique_ptr<Node> frame(Child child) {
+  return std::make_unique<Frame>(unpack(std::move(child)));
+}
+
+std::unique_ptr<Node> frame(Child title, Child content) {
+  return std::make_unique<Frame>(unpack(std::move(content), std::move(title)));
+}
+
+};  // namespace dom
+};  // namespace ftxui
diff --git a/ftxui/src/ftxui/core/dom/gauge.cpp b/ftxui/src/ftxui/dom/gauge.cpp
similarity index 92%
rename from ftxui/src/ftxui/core/dom/gauge.cpp
rename to ftxui/src/ftxui/dom/gauge.cpp
index 8b6756fc5e065bb96af3f6299c47188e84a662fd..603d5e2722268ec7706a916347316cbe5066717b 100644
--- a/ftxui/src/ftxui/core/dom/gauge.cpp
+++ b/ftxui/src/ftxui/dom/gauge.cpp
@@ -1,5 +1,5 @@
-#include "ftxui/core/dom/node.hpp"
-#include "ftxui/core/dom/elements.hpp"
+#include "ftxui/dom/node.hpp"
+#include "ftxui/dom/elements.hpp"
 
 namespace ftxui {
 namespace dom {
diff --git a/ftxui/src/ftxui/dom/gauge_test.cpp b/ftxui/src/ftxui/dom/gauge_test.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..c3f88814d216c6a6755023ee08538c26a30ed436
--- /dev/null
+++ b/ftxui/src/ftxui/dom/gauge_test.cpp
@@ -0,0 +1,34 @@
+#include "ftxui/dom/elements.hpp"
+#include "ftxui/screen.hpp"
+#include "gtest/gtest.h"
+
+namespace ftxui {
+namespace dom {
+
+TEST(GaugeTest, zero) {
+  auto root = gauge(0);
+  Screen screen(11,1);
+  Render(screen, root.get());
+
+  EXPECT_EQ("           ", screen.ToString());
+}
+
+TEST(GaugeTest, half) {
+  auto root = gauge(0.5);
+  Screen screen(11,1);
+  Render(screen, root.get());
+
+  EXPECT_EQ("█████▏▋    ", screen.ToString());
+//"  ▏▎▍▌▊▉█";
+}
+
+TEST(GaugeTest, one) {
+  auto root = gauge(1.0);
+  Screen screen(11,1);
+  Render(screen, root.get());
+
+  EXPECT_EQ("███████████", screen.ToString());
+}
+
+} // namespace dom
+} // namespace ftxui
diff --git a/ftxui/src/ftxui/core/dom/hbox.cpp b/ftxui/src/ftxui/dom/hbox.cpp
similarity index 95%
rename from ftxui/src/ftxui/core/dom/hbox.cpp
rename to ftxui/src/ftxui/dom/hbox.cpp
index dfd66d7149630060d7c5b95c8a371e583e0bb01f..a96049e26e07abf0d2a92dc8ae57324784e6d556 100644
--- a/ftxui/src/ftxui/core/dom/hbox.cpp
+++ b/ftxui/src/ftxui/dom/hbox.cpp
@@ -1,5 +1,5 @@
-#include "ftxui/core/dom/node.hpp"
-#include "ftxui/core/dom/elements.hpp"
+#include "ftxui/dom/node.hpp"
+#include "ftxui/dom/elements.hpp"
 
 namespace ftxui {
 namespace dom {
diff --git a/ftxui/src/ftxui/core/dom/hbox_test.cpp b/ftxui/src/ftxui/dom/hbox_test.cpp
similarity index 96%
rename from ftxui/src/ftxui/core/dom/hbox_test.cpp
rename to ftxui/src/ftxui/dom/hbox_test.cpp
index fb05538405c70a6881225b1a69a53f527470dbb9..83f775bd906cd274e62751571de2a2858af69ce1 100644
--- a/ftxui/src/ftxui/core/dom/hbox_test.cpp
+++ b/ftxui/src/ftxui/dom/hbox_test.cpp
@@ -1,5 +1,5 @@
-#include "ftxui/core/dom/elements.hpp"
-#include "ftxui/core/screen.hpp"
+#include "ftxui/dom/elements.hpp"
+#include "ftxui/screen.hpp"
 #include "gtest/gtest.h"
 
 namespace ftxui {
diff --git a/ftxui/src/ftxui/dom/inverted.cpp b/ftxui/src/ftxui/dom/inverted.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..2f4afdb87e6623248ffa2b1b7dc63c5d338ada0d
--- /dev/null
+++ b/ftxui/src/ftxui/dom/inverted.cpp
@@ -0,0 +1,37 @@
+#include "ftxui/dom/node.hpp"
+#include "ftxui/dom/elements.hpp"
+
+namespace ftxui {
+namespace dom {
+
+class Inverted : public Node {
+ public:
+  Inverted(Children children) : Node(std::move(children)) {}
+  ~Inverted() override {}
+
+  void ComputeRequirement() override {
+    Node::ComputeRequirement();
+    requirement_ = children[0]->requirement();
+  }
+
+  void SetBox(Box box) override {
+    Node::SetBox(box);
+    children[0]->SetBox(box);
+  }
+
+  void Render(Screen& screen) override {
+    Node::Render(screen);
+    for (int y = box_.top; y <= box_.bottom; ++y) {
+      for (int x = box_.left; x <= box_.right; ++x) {
+        screen.PixelAt(x,y).inverted = true; 
+      }
+    }
+  }
+};
+
+std::unique_ptr<Node> inverted(Child child) {
+  return std::make_unique<Inverted>(unpack(std::move(child)));
+}
+
+};  // namespace dom
+};  // namespace ftxui
diff --git a/ftxui/src/ftxui/core/dom/node.cpp b/ftxui/src/ftxui/dom/node.cpp
similarity index 84%
rename from ftxui/src/ftxui/core/dom/node.cpp
rename to ftxui/src/ftxui/dom/node.cpp
index db6b2669aa43ecf9cdfe22c34d262a1af89711ac..648c1211958d62c5a9659428484645bfa1ce8d9b 100644
--- a/ftxui/src/ftxui/core/dom/node.cpp
+++ b/ftxui/src/ftxui/dom/node.cpp
@@ -1,4 +1,4 @@
-#include "ftxui/core/dom/node.hpp"
+#include "ftxui/dom/node.hpp"
 
 namespace ftxui {
 namespace dom {
@@ -8,10 +8,15 @@ Node::Node(std::vector<std::unique_ptr<Node>> children)
     : children(std::move(children)) {}
 Node::~Node() {}
 
-void Node::ComputeRequirement() {}
+void Node::ComputeRequirement() {
+  for(auto& child : children)
+    child->ComputeRequirement();
+}
+
 void Node::SetBox(Box box) {
   box_ = box;
 }
+
 void Node::Render(Screen& screen) {
   for(auto& child : children)
     child->Render(screen);
diff --git a/ftxui/src/ftxui/core/dom/separator.cpp b/ftxui/src/ftxui/dom/separator.cpp
similarity index 95%
rename from ftxui/src/ftxui/core/dom/separator.cpp
rename to ftxui/src/ftxui/dom/separator.cpp
index cf9a15821b5d6a45c2ac8c7b2ee0e5c056344331..db22aeb1293ce309c7f936ddd11a12491bf68956 100644
--- a/ftxui/src/ftxui/core/dom/separator.cpp
+++ b/ftxui/src/ftxui/dom/separator.cpp
@@ -1,4 +1,4 @@
-#include "ftxui/core/dom/node.hpp"
+#include "ftxui/dom/node.hpp"
 
 namespace ftxui {
 namespace dom {
diff --git a/ftxui/src/ftxui/core/dom/text.cpp b/ftxui/src/ftxui/dom/text.cpp
similarity index 94%
rename from ftxui/src/ftxui/core/dom/text.cpp
rename to ftxui/src/ftxui/dom/text.cpp
index 7b604fb46d97478b1db47c9089b8add8ce0a6632..218ed06fc4eaa418e2905596cb4f16214e611e08 100644
--- a/ftxui/src/ftxui/core/dom/text.cpp
+++ b/ftxui/src/ftxui/dom/text.cpp
@@ -1,4 +1,4 @@
-#include "ftxui/core/dom/node.hpp"
+#include "ftxui/dom/node.hpp"
 
 namespace ftxui {
 namespace dom {
diff --git a/ftxui/src/ftxui/core/dom/text_test.cpp b/ftxui/src/ftxui/dom/text_test.cpp
similarity index 92%
rename from ftxui/src/ftxui/core/dom/text_test.cpp
rename to ftxui/src/ftxui/dom/text_test.cpp
index 72775ac0286605ba18ffcf6132419b8fca442a8c..f18f99d54029376864386671091d299efb5770ca 100644
--- a/ftxui/src/ftxui/core/dom/text_test.cpp
+++ b/ftxui/src/ftxui/dom/text_test.cpp
@@ -1,5 +1,5 @@
-#include "ftxui/core/dom/elements.hpp"
-#include "ftxui/core/screen.hpp"
+#include "ftxui/dom/elements.hpp"
+#include "ftxui/screen.hpp"
 #include "gtest/gtest.h"
 
 namespace ftxui {
diff --git a/ftxui/src/ftxui/dom/underlined.cpp b/ftxui/src/ftxui/dom/underlined.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..07f714fcdd710aa652ff26c3b5b43c20fd3a7863
--- /dev/null
+++ b/ftxui/src/ftxui/dom/underlined.cpp
@@ -0,0 +1,37 @@
+#include "ftxui/dom/node.hpp"
+#include "ftxui/dom/elements.hpp"
+
+namespace ftxui {
+namespace dom {
+
+class Underlined : public Node {
+ public:
+  Underlined(Children children) : Node(std::move(children)) {}
+  ~Underlined() override {}
+
+  void ComputeRequirement() override {
+    Node::ComputeRequirement();
+    requirement_ = children[0]->requirement();
+  }
+
+  void SetBox(Box box) override {
+    Node::SetBox(box);
+    children[0]->SetBox(box);
+  }
+
+  void Render(Screen& screen) override {
+    Node::Render(screen);
+    for (int y = box_.top; y <= box_.bottom; ++y) {
+      for (int x = box_.left; x <= box_.right; ++x) {
+        screen.PixelAt(x,y).underlined = true; 
+      }
+    }
+  }
+};
+
+std::unique_ptr<Node> underlined(Child child) {
+  return std::make_unique<Underlined>(unpack(std::move(child)));
+}
+
+};  // namespace dom
+};  // namespace ftxui
diff --git a/ftxui/src/ftxui/core/dom/vbox.cpp b/ftxui/src/ftxui/dom/vbox.cpp
similarity index 95%
rename from ftxui/src/ftxui/core/dom/vbox.cpp
rename to ftxui/src/ftxui/dom/vbox.cpp
index 15566215c5793d5c6561d0762cc5fc724b9bc959..3f504e60cc48b139ee994b4fd6e1ee2befdb6645 100644
--- a/ftxui/src/ftxui/core/dom/vbox.cpp
+++ b/ftxui/src/ftxui/dom/vbox.cpp
@@ -1,5 +1,5 @@
-#include "ftxui/core/dom/node.hpp"
-#include "ftxui/core/dom/elements.hpp"
+#include "ftxui/dom/node.hpp"
+#include "ftxui/dom/elements.hpp"
 
 namespace ftxui {
 namespace dom {
diff --git a/ftxui/src/ftxui/core/dom/vbox_test.cpp b/ftxui/src/ftxui/dom/vbox_test.cpp
similarity index 95%
rename from ftxui/src/ftxui/core/dom/vbox_test.cpp
rename to ftxui/src/ftxui/dom/vbox_test.cpp
index f9005a6f78462098cac1264451607d9907a306a0..912c349109be4e669a936f48a8f02f14ca04df60 100644
--- a/ftxui/src/ftxui/core/dom/vbox_test.cpp
+++ b/ftxui/src/ftxui/dom/vbox_test.cpp
@@ -1,5 +1,5 @@
-#include "ftxui/core/dom/elements.hpp"
-#include "ftxui/core/screen.hpp"
+#include "ftxui/dom/elements.hpp"
+#include "ftxui/screen.hpp"
 #include "gtest/gtest.h"
 
 namespace ftxui {
diff --git a/ftxui/src/ftxui/screen.cpp b/ftxui/src/ftxui/screen.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..cbb54975daea2e7fcde389e2c1d49d5519935538
--- /dev/null
+++ b/ftxui/src/ftxui/screen.cpp
@@ -0,0 +1,91 @@
+#include "ftxui/dom/node.hpp"
+#include "ftxui/screen.hpp"
+#include "ftxui/terminal.hpp"
+#include "ftxui/util/string.hpp"
+
+#include <sstream>
+
+namespace ftxui {
+
+Screen::Screen(size_t dimx, size_t dimy)
+    : dimx_(dimx), dimy_(dimy), pixels_(dimy, std::vector<Pixel>(dimx)) {}
+
+std::string Screen::ToString() {
+  std::wstringstream ss;
+  
+  Pixel previous_pixel;
+
+  for (size_t y = 0; y < dimy_; ++y) {
+    for (size_t x = 0; x < dimx_; ++x) {
+      if (pixels_[y][x].bold != previous_pixel.bold) {
+        if (pixels_[y][x].bold) {
+          ss << L"\e[1m";
+        } else {
+          ss << L"\e[0m";
+        }
+      }
+      if (pixels_[y][x].inverted != previous_pixel.inverted) {
+        if (pixels_[y][x].inverted) {
+          ss << L"\e[7m";
+        } else {
+          ss << L"\e[27m";
+        }
+      }
+      if (pixels_[y][x].underlined != previous_pixel.underlined) {
+        if (pixels_[y][x].underlined) {
+          ss << L"\e[4m";
+        } else {
+          ss << L"\e[24m";
+        }
+      }
+      if (pixels_[y][x].dim != previous_pixel.dim) {
+        if (pixels_[y][x].dim) {
+          ss << L"\e[2m";
+        } else {
+          ss << L"\e[22m";
+        }
+      }
+      ss << pixels_[y][x].character;
+      previous_pixel = pixels_[y][x];
+    }
+    if (y + 1 < dimy_)
+      ss << '\n';
+  }
+  return to_string(ss.str());
+}
+
+wchar_t& Screen::at(size_t x, size_t y) {
+  return pixels_[y][x].character;
+}
+
+Pixel& Screen::PixelAt(size_t x, size_t y) {
+  return pixels_[y][x];
+}
+
+// static
+Screen Screen::TerminalFullscreen() {
+  Terminal::Dimensions size = Terminal::Size();
+  return Screen(size.dimx, size.dimy);
+}
+
+// static
+Screen Screen::TerminalOutput(std::unique_ptr<dom::Node>& element) {
+  element->ComputeRequirement();
+  Terminal::Dimensions size = Terminal::Size();
+  return Screen(size.dimx, element->requirement().min.y);
+}
+
+std::string Screen::ResetPosition() {
+  std::stringstream ss;
+  for(size_t y = 1; y<dimy_; ++y) {
+    ss << "\e[2K\r\e[1A";
+  }
+  return ss.str();
+}
+
+void Screen::Clear() {
+  pixels_ = std::vector<std::vector<Pixel>>(dimy_,
+                                            std::vector<Pixel>(dimx_, Pixel()));
+}
+
+};  // namespace ftxui
diff --git a/ftxui/src/ftxui/screen_interactive.cpp b/ftxui/src/ftxui/screen_interactive.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..7d35943183cba3dda64f40dc644b3ec82dd83f4c
--- /dev/null
+++ b/ftxui/src/ftxui/screen_interactive.cpp
@@ -0,0 +1,112 @@
+#include "ftxui/screen_interactive.hpp"
+#include "ftxui/component/component.hpp"
+#include "ftxui/component/delegate.hpp"
+#include <iostream>
+#include <stdio.h>
+#include <termios.h>
+#include <unistd.h>
+
+namespace ftxui {
+
+class ScreenInteractive::Delegate : public component::Delegate {
+ public:
+  Delegate() : root_(this) {}
+
+  void Register(component::Component* c) override { component_ = c; }
+
+  std::vector<std::unique_ptr<Delegate>> child_;
+  Delegate* NewChild() override {
+    Delegate* child = new Delegate;
+    child->root_ = root_;
+    child->parent_ = this;
+
+    if (!child_.empty()) {
+      child_.back()->next_sibling_ = child;
+      child->previous_sibling_ = child_.back().get();
+    }
+
+    child_.emplace_back(child);
+    return child;
+  }
+
+  void Event(int key) { component_->Event(key); }
+
+
+  std::vector<component::Delegate*> children() override {
+    std::vector<component::Delegate*> ret;
+    for (auto& it : child_)
+      ret.push_back(it.get());
+    return ret;
+  }
+
+  Delegate* root_;
+  Delegate* parent_ = nullptr;
+  Delegate* previous_sibling_ = nullptr;
+  Delegate* next_sibling_ = nullptr;
+  component::Component* component_;
+
+  Delegate* Root() override { return root_; }
+  Delegate* Parent() override { return parent_; }
+  Delegate* PreviousSibling() override { return previous_sibling_; }
+  Delegate* NextSibling() override { return next_sibling_; }
+  component::Component* component() override { return component_; }
+};
+
+ScreenInteractive::ScreenInteractive(size_t dimx, size_t dimy)
+    : Screen(dimx, dimy), delegate_(new Delegate) {}
+ScreenInteractive::~ScreenInteractive() {}
+
+void ScreenInteractive::Loop() {
+  std::cout << "\033[?9h";    /* Send Mouse Row & Column on Button Press */
+  std::cout << "\033[?1000h"; /* Send Mouse X & Y on button press and release */
+  std::cout << std::flush;
+
+  // Save the old terminal configuration.
+  struct termios terminal_configuration_old;
+  tcgetattr(STDIN_FILENO, &terminal_configuration_old);
+
+  // Set the new terminal configuration
+  struct termios terminal_configuration_new;
+  terminal_configuration_new = terminal_configuration_old;
+
+  // Non canonique terminal.
+  terminal_configuration_new.c_lflag &= ~ICANON;
+  // Do not print after a key press.
+  terminal_configuration_new.c_lflag &= ~ECHO;
+  tcsetattr(STDIN_FILENO, TCSANOW, &terminal_configuration_new);
+
+  Draw();
+  while (!quit_) {
+    int key = getchar();
+    delegate_->Event(key);
+
+    Clear();
+    Draw();
+  }
+  std::cout << std::endl;
+  //Clear();
+
+  // Restore the old terminal configuration.
+  tcsetattr(STDIN_FILENO, TCSANOW, &terminal_configuration_old);
+}
+
+void ScreenInteractive::Draw() {
+  auto document = delegate_->component()->Render();
+  Render(*this, document.get());
+  std::cout << ToString() << std::flush;
+}
+
+void ScreenInteractive::Clear() {
+  std::cout << ResetPosition();
+  Screen::Clear();
+}
+
+component::Delegate* ScreenInteractive::delegate() {
+  return delegate_.get();
+}
+
+std::function<void()> ScreenInteractive::ExitLoopClosure() {
+  return [this]() { quit_ = true; };
+}
+
+}  // namespace ftxui
diff --git a/ftxui/src/ftxui/core/terminal.cpp b/ftxui/src/ftxui/terminal.cpp
similarity index 87%
rename from ftxui/src/ftxui/core/terminal.cpp
rename to ftxui/src/ftxui/terminal.cpp
index f8bf7c80149ead129bfed172501990f03ed59b60..b8e1347933c2896be6d0d767b8220d5379751c93 100644
--- a/ftxui/src/ftxui/core/terminal.cpp
+++ b/ftxui/src/ftxui/terminal.cpp
@@ -2,7 +2,7 @@
 #include <stdio.h>
 #include <unistd.h>
 
-#include "ftxui/core/terminal.hpp"
+#include "ftxui/terminal.hpp"
 
 namespace ftxui {
 
diff --git a/ftxui/src/ftxui/core/terminal.hpp b/ftxui/src/ftxui/terminal.hpp
similarity index 100%
rename from ftxui/src/ftxui/core/terminal.hpp
rename to ftxui/src/ftxui/terminal.hpp
diff --git a/tutorials/dom_elements.md b/tutorials/dom_elements.md
new file mode 100644
index 0000000000000000000000000000000000000000..ca41158aa1faca1593b897352b34b6f97d4be2b0
--- /dev/null
+++ b/tutorials/dom_elements.md
@@ -0,0 +1,141 @@
+All the dom element are declared in one header:
+"""c++
+#include <ftxui/dom/elements.hpp>
+"""
+
+It declares the following set of elements:
+
+"""C++
+// --- Layout ----
+Element vbox(Children);
+Element hbox(Children);
+Element flex();
+
+// --- Widget --
+Element text(std::wstring text);
+Element separator();
+Element gauge(float ratio);
+Element frame(Child);
+Element frame(Child title, Child content);
+
+// -- Decorator (Style) ---
+Element bold(Element);
+Element dim(Element);
+Element inverted(Element);
+Element underlined(Element);
+
+// --- Decorator ---
+Element hcenter(Element);
+Element vcenter(Element);
+Element center(Element);
+Element flex(Element);
+"""
+
+# Layout elements.
+
+vbox (Vertical-box) and hbox (Horizontal-box) are containers. They are used to
+compose all the elements together. They will display their children one by one in one direction.
+Each elements will occupy the space it required plus a fraction of the remaining
+space dispatched to all the flexible elements.
+
+flex() is used to make an element flexible.
+
+## Examples
+"""C++
+  hbox(
+    frame(text(L"left")),
+    flex(frame(text(L"middle"))),
+    frame(text(L"right"))
+  );
+"""
+"""bash
+┌────┐┌─────────────────────────────────────────────────────────────────┐┌─────┐
+│left││middle                                                           ││right│
+└────┘└─────────────────────────────────────────────────────────────────┘└─────┘
+"""
+
+"""C++
+  hbox(
+    frame(text(L"left")),
+    flex(frame(text(L"middle"))),
+    flex(frame(text(L"right")))
+  );
+"""
+"""bash
+┌────┐┌───────────────────────────────────┐┌───────────────────────────────────┐
+│left││middle                             ││right                              │
+└────┘└───────────────────────────────────┘└───────────────────────────────────┘
+"""
+
+# Widget elements.
+
+## text
+
+The more simple widget. It display a text.
+"""C++
+  text(L"I am a piece of text");
+"""
+"""bash
+I am a piece of text.
+"""
+
+## frame
+Add a border arround an element
+"""c+
+frame(text(L"The element"))
+"""
+
+"""bash
+┌───────────┐
+│The element│
+└───────────┘
+"""
+
+## separator
+
+Display a vertical or horizontal line to visually split the content of a
+container in two.
+
+"""c++
+frame(hbox(
+	vbox(
+		text(L"left top"),
+		text(L"left bottom")
+	),
+	separator(),
+	vbox(
+		text(L"right top"),
+		text(L"right bottom")
+	)
+));
+"""
+
+"""bash
+┌───────────┬────────────┐
+│left top   │right top   │
+│left bottom│right bottom│
+└───────────┴────────────┘
+"""
+
+## gauge
+
+
+A gauge. It can be used to represent a progress bar.
+"""c+
+frame(gauge(0.5))
+"""
+
+"""bash
+┌────────────────────────────────────────────────────────────────────────────┐
+│██████████████████████████████████████                                      │
+└────────────────────────────────────────────────────────────────────────────┘
+"""
+
+# Decorator (style)
+A terminal console can usually display colored text and colored background.
+The text can also have different effects: bold, dim, underlined, inverted.
+
+Element bold(Element);
+Element dim(Element);
+Element inverted(Element);
+Element underlined(Element);