diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml
index 353b04608c06572a50f3f6537cb114477cc2de8c..68e240af5d71175d1f096781aa31ca65d75f45e8 100644
--- a/.github/workflows/build.yaml
+++ b/.github/workflows/build.yaml
@@ -216,6 +216,8 @@ jobs:
           rsync -amv
           --include='*/'
           --include='*.html'
+          --include='*.css'
+          --include='*.mjs'
           --include='*.js'
           --include='*.wasm'
           --exclude='*'
diff --git a/.gitignore b/.gitignore
index 708338eced79c691e79b85eef5c0fb8138a0822d..735ed65b7c9f1967b928c55fc74971bc91004ca6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -34,14 +34,16 @@
 !doc/**/*.md
 
 # examples directory:
-!examples/**/*.txt
 !examples/**/*.cpp
+!examples/**/*.css
 !examples/**/*.hpp
-!examples/**/*.ipp
 !examples/**/*.html
-!examples/**/*.py
-!examples/**/*.js
 !examples/**/*.html.disabled
+!examples/**/*.ipp
+!examples/**/*.js
+!examples/**/*.mjs
+!examples/**/*.py
+!examples/**/*.txt
 
 # include directory:
 !include/ftxui/**/*.hpp
diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt
index dbea321e13e773e69807817c1d31f8a96757acdb..953efa98ad52c75b06a2329ca90bdb1fdb437651 100644
--- a/examples/CMakeLists.txt
+++ b/examples/CMakeLists.txt
@@ -21,6 +21,8 @@ if (EMSCRIPTEN)
   get_property(EXAMPLES GLOBAL PROPERTY FTXUI::EXAMPLES)
   foreach(file
       "index.html"
+      "index.mjs"
+      "index.css"
       "sw.js"
       "run_webassembly.py")
     configure_file(${file} ${file})
diff --git a/examples/index.css b/examples/index.css
new file mode 100644
index 0000000000000000000000000000000000000000..32b44750f62a1f25c8d6c8072385e699dbd5c628
--- /dev/null
+++ b/examples/index.css
@@ -0,0 +1,107 @@
+@import url(https://fonts.googleapis.com/css?family=Khula:700);
+
+body {
+  background-color:#EEE;
+  padding:0px;
+  margin:0px;
+  font-family: Khula, Helvetica, sans-serif;
+  font-size: 130%;
+}
+
+.page {
+  max-width:1300px;
+  margin: auto;
+  padding: 10px;
+}
+
+a {
+  box-shadow: inset 0 0 0 0 #54b3d6;
+  color: #0087b9;
+  margin: 0 -.25rem;
+  padding: 0 .25rem;
+  transition: color .3s ease-in-out,
+              box-shadow .3s ease-in-out;
+}
+
+a:hover {
+  box-shadow: inset 120px 0 0 0 #54b3d6;
+  color: white;
+}
+
+h1 {
+  text-decoration: underline;
+  width:100%;
+  background-color: rgba(100,100,255,0.5);
+  padding: 10px;
+  margin: 0;
+}
+
+
+#selectExample {
+  flex:1;
+}
+
+#selectExample, #selectExample option {
+  font-size: 16px;
+  font-family: sans-serif;
+  font-weight: 700;
+  line-height: 1.3;
+  border:0px;
+  background-color: #bbb;
+  color:black;
+}
+
+#selectExample:focus {
+  outline:none;
+}
+
+#terminal {
+  width:100%;
+  height 500px;
+  height: calc(clamp(200px, 100vh - 300px, 900px));
+  overflow: hidden;
+  border:none;
+  background-color:black;
+}
+
+#terminalContainer {
+  overflow: hidden;
+  border-radius: 10px;
+  box-shadow: 0px 2px 10px 0px rgba(0,0,0,0.75),
+  0px 2px 80px 0px rgba(0,0,0,0.50);
+}
+
+.fakeButtons {
+  height: 10px;
+  width: 10px;
+  border-radius: 50%;
+  border: 1px solid #000;
+  margin:6px;
+  background-color: #ff3b47;
+  border-color: #9d252b;
+  display: inline-block;
+}
+
+.fakeMinimize {
+  left: 11px;
+  background-color: #ffc100;
+  border-color: #9d802c;
+}
+
+.fakeZoom {
+  left: 16px;
+  background-color: #00d742;
+  border-color: #049931;
+}
+
+.fakeMenu {
+  display:flex;
+  flex-direction: row;
+  width:100%;
+  box-sizing: border-box;
+  height: 25px;
+  background-color: #bbb;
+  color:black;
+  margin: 0 auto;
+  overflow: hidden;
+}
diff --git a/examples/index.html b/examples/index.html
index a5e0a48644342d367ad11813fcbe876388022c47..8e5498c31adeeba9c0fe7a7b1865f4f11304ca7b 100644
--- a/examples/index.html
+++ b/examples/index.html
@@ -1,173 +1,32 @@
-<!DOCTYPE html> <html lang="en">
+<!DOCTYPE html>
+<html lang="en">
   <head>
     <meta charset="utf-8">
     <title>FTXUI examples WebAssembly</title>
-    <script src="https://cdn.jsdelivr.net/npm/xterm@4.18.0/lib/xterm.min.js"></script>
-    <script src="https://cdn.jsdelivr.net/npm/xterm-addon-webgl@0.11.4/lib/xterm-addon-webgl.min.js"></script>
-    <script src="https://cdn.jsdelivr.net/npm/xterm-addon-fit@0.5.0/lib/xterm-addon-fit.min.js"></script>
+    <link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>➡️</text></svg>">
+    <link rel="stylesheet" href="index.css">
     <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/xterm@4.11.0/css/xterm.css"></link>
-    <!--Add COOP/COEP via a ServiceWorker to use SharedArrayBuffer-->
-    <script>
-      if ("serviceWorker" in navigator && !window.crossOriginIsolated) {
-        navigator.serviceWorker.register(new URL("./sw.js", location.href)).then(
-          registration => {
-            if (registration.active && !navigator.serviceWorker.controller) {
-              window.location.reload();
-            }
-          },
-        );
-      } 
-    </script>
+    <script type="module" src="index.mjs"></script>
   </head>
   <body>
     <script id="example_script"></script>
+
     <div class="page">
-      <h1>FTXUI WebAssembly Example </h1>
-      <p>
-        <a href="https://github.com/ArthurSonzogni/FTXUI">FTXUI</a> is a single
-        C++ library for terminal user interface.
-      </p>
       <p>
-        On this page, you can try all the examples contained in: <a
-        href="https://github.com/ArthurSonzogni/FTXUI/tree/master/examples">./example/</a>
-        Those are compiled using WebAssembly.
+        <a href="https://github.com/ArthurSonzogni/FTXUI">FTXUI</a> is a simple
+        functional C++ library for terminal user interface. <br/>
+        This showcase the: <a href="https://github.com/ArthurSonzogni/FTXUI/tree/master/examples">./example/</a> folder. <br/>
       </p>
-      <select id="selectExample"></select>
-      <div id="terminal"></div>
+
+      <div id="terminalContainer">
+        <div class="fakeMenu">
+          <div class="fakeButtons fakeClose"></div>
+          <div class="fakeButtons fakeMinimize"></div>
+          <div class="fakeButtons fakeZoom"></div>
+          <select id="selectExample"></select>
+        </div>
+        <div id="terminal"></div>
+      </div>
     </div>
   </body>
-  <script>
-    const example_list = "@EXAMPLES@".split(";");
-
-    const url_search_params = new URLSearchParams(window.location.search);
-    const example = url_search_params.get("file") || "dom/color_gallery";
-    const select = document.getElementById("selectExample"); 
-
-    for(var i = 0; i < example_list.length; i++) {
-        var opt = example_list[i];
-        var el = document.createElement("option");
-        el.textContent = opt;
-        el.value = opt;
-        select.appendChild(el);
-    }
-    select.selectedIndex = example_list.findIndex(path => path == example) || 0;
-    select.addEventListener("change", () => {
-      location.href = (location.href).split('?')[0] + "?file=" +
-            example_list[select.selectedIndex];
-    });
-
-    let stdin_buffer = [];
-    const stdin = () => {
-      return stdin_buffer.shift() || 0;
-    }
-
-    let stdout_buffer = [];
-    const stdout = code => {
-      if (code == 0) {
-        term.write(new Uint8Array(stdout_buffer));
-        stdout_buffer = [];
-      } else {
-        stdout_buffer.push(code)
-      }
-    }
-    let stderrbuffer = [];
-    const stderr = code => {
-      if (code == 0 || code == 10) {
-        console.error(String.fromCodePoint(...stderrbuffer));
-        stderrbuffer = [];
-      } else {
-        stderrbuffer.push(code)
-      }
-    }
-    const term = new Terminal();
-    const term_element = document.querySelector('#terminal');
-    term.open(term_element);
-
-    const webgl_addon = new (WebglAddon.WebglAddon)();
-    term.loadAddon(webgl_addon);
-
-    const onBinary = e => {
-      for(c of e)
-        stdin_buffer.push(c.charCodeAt(0));
-    }
-    term.onBinary(onBinary);
-    term.onData(onBinary)
-    term.resize(140,43);
-    window.Module = {
-      preRun: () => {
-        FS.init(stdin, stdout, stderr);
-      },
-      postRun: [],
-      onRuntimeInitialized: () => {
-        if (window.Module._ftxui_on_resize == undefined)
-          return;
-
-        const fit_addon = new (FitAddon.FitAddon)();
-        term.loadAddon(fit_addon);
-        fit_addon.fit();
-        const resize_handler = () => {
-          const {cols, rows} = fit_addon.proposeDimensions();
-          term.resize(cols, rows);
-          window.Module._ftxui_on_resize(cols, rows);
-        };
-        const resize_observer = new ResizeObserver(resize_handler);
-        resize_observer.observe(term_element);
-        resize_handler();
-
-        // Disable scrollbar
-        term.write('\x1b[?47h')
-      },
-    };
-
-    const words = example.split('/')
-    words[1] = "ftxui_example_" + words[1] + ".js"
-    document.querySelector("#example_script").src = words.join('/');
-  </script>
-
-  <style>
-
-    body {
-      background-color:#EEE;
-      padding:20px;
-      font-family: Helvetica, sans-serif;
-      font-size: 130%;
-    }
-
-    .page {
-      max-width:1300px;
-      margin: auto;
-    }
-
-    h1 {
-      text-decoration: underline;
-    }
-
-    select {
-      display:block;
-      padding: .6em 1.4em .5em .8em;
-      border-radius: 20px 20px 0px 0px;
-      font-size: 16px;
-      font-family: sans-serif;
-      font-weight: 700;
-
-      color: #444;
-      line-height: 1.3;
-      background-color:black;
-      border:0px;
-      color:white;
-      transition: color 0.2s linear;
-      transition: background-color 0.2s linear;
-    }
-
-    #terminal {
-      width:100%;
-      height: 500px;
-      height: calc(clamp(200px, 100vh - 300px, 900px));
-      overflow: hidden;
-      border:none;
-      padding:auto;
-    }
-
-  </style>
-
 </html>
diff --git a/examples/index.mjs b/examples/index.mjs
new file mode 100644
index 0000000000000000000000000000000000000000..722b224471feb22837a571139a02019c2b868a16
--- /dev/null
+++ b/examples/index.mjs
@@ -0,0 +1,102 @@
+import xterm             from 'https://cdn.jsdelivr.net/npm/xterm@4.18.0/+esm'
+import xterm_addon_webgl from 'https://cdn.jsdelivr.net/npm/xterm-addon-webgl@0.11.4/+esm'
+import xterm_addon_fit   from 'https://cdn.jsdelivr.net/npm/xterm-addon-fit@0.5.0/+esm'
+
+// Add COOP/COEP via a ServiceWorker to use SharedArrayBuffer
+if ("serviceWorker" in navigator && !window.crossOriginIsolated) {
+  const url_sw = new URL("./sw.js", location.href);
+  const registration = await navigator.serviceWorker.register(url_sw);
+  if (registration.active && !navigator.serviceWorker.controller) {
+    window.location.reload(); // Reload to ensure the COOP/COEP headers are set.
+  }
+} 
+
+const example_list = "@EXAMPLES@".split(";");
+const url_search_params = new URLSearchParams(window.location.search);
+
+const select = document.getElementById("selectExample"); 
+for(const example of example_list) {
+  const option = document.createElement("option");
+  option.textContent = example;
+  option.value = example;
+  select.appendChild(option);
+}
+const example = url_search_params.get("file") || "dom/color_gallery";
+select.selectedIndex = example_list.findIndex(path => path == example) || 0;
+select.addEventListener("change", () => {
+  history.pushState({}, "", "?file=" + example_list[select.selectedIndex]);
+  location.reload();
+});
+
+const term_element = document.querySelector('#terminal');
+const term = new xterm.Terminal();
+term.options.scrollback = 0;
+term.open(term_element);
+const fit_addon = new xterm_addon_fit.FitAddon();
+const webgl_addon = new xterm_addon_webgl.WebglAddon();
+term.loadAddon(webgl_addon);
+term.loadAddon(fit_addon);
+
+const stdin_buffer = [];
+const stdout_buffer = [];
+const stderr_buffer = [];
+
+const stdin = () => {
+  return stdin_buffer.shift() || 0;
+}
+
+const stdout = code => {
+  if (code == 0) {
+    term.write(new Uint8Array(stdout_buffer));
+    stdout_buffer.length = 0;
+  } else {
+    stdout_buffer.push(code)
+  }
+}
+
+const stderr = code => {
+  if (code == 0 || code == 10) {
+    console.error(String.fromCodePoint(...stderr_buffer));
+    stderr_buffer = [];
+  } else {
+    stderr_buffer.push(code)
+  }
+}
+
+const onBinary = e => {
+  for(const c of e)
+    stdin_buffer.push(c.charCodeAt(0));
+}
+
+term.onBinary(onBinary);
+term.onData(onBinary)
+term.resize(140,43);
+
+window.Module = {
+  preRun: () => {
+    FS.init(stdin, stdout, stderr);
+  },
+  postRun: [],
+  onRuntimeInitialized: () => {
+    if (window.Module._ftxui_on_resize == undefined)
+      return;
+    fit_addon.fit();
+
+    const resize_handler = () => {
+      const {cols, rows} = fit_addon.proposeDimensions();
+      term.resize(cols, rows);
+      window.Module._ftxui_on_resize(cols, rows);
+      fit_addon.fit();
+    };
+    const resize_observer = new ResizeObserver(resize_handler);
+    resize_observer.observe(term_element);
+    resize_handler();
+
+    // Disable scrollbar
+    //term.write('\x1b[?47h')
+  },
+};
+
+const words = example.split('/')
+words[1] = "ftxui_example_" + words[1] + ".js"
+document.querySelector("#example_script").src = words.join('/');