diff --git a/index.html b/index.html
index 83334ac402d86c426d91a2b84a9988dfd6fc9c21..ad6337906bc2608d96d8edc65d7cd2c9e399d75e 100644
--- a/index.html
+++ b/index.html
@@ -43,7 +43,7 @@
     <script>
         window.CHATTERBOX_CONFIG_LOCATION = "./config.json";
     </script>
-    <script src="./src/parent.ts" type="module" id="chatterbox-script"></script>
+    <script src="./src/parent/parent.ts" type="module" id="chatterbox-script"></script>
 </body>
 
 </html>
diff --git a/parent-vite.config.js b/parent-vite.config.js
index 7eb85dcfa952580a2434ce44b1e2fd2bfa9aa373..da7cae97c4e4d02eedd4ffe5505464b8ae8e1416 100644
--- a/parent-vite.config.js
+++ b/parent-vite.config.js
@@ -1,5 +1,11 @@
+/**
+ * We do a second build for parent (the first one builds both parent and chatterbox-app) because we need
+ * the link to the CSS file for parent with the asset-hash included.
+ */
 const { defineConfig } = require("vite")
 const { resolve } = require("path");
+
+// We've configured the first build to produce a manifest.json that tells us what the asset-hashed file names are.
 import manifestJSON from "./target/manifest.json";
 
 const cssLink = manifestJSON["index.html"]["css"][0];
diff --git a/src/parent.ts b/src/parent.ts
deleted file mode 100644
index 208267a72b40a1a3174ecb72f5694db46a8e7700..0000000000000000000000000000000000000000
--- a/src/parent.ts
+++ /dev/null
@@ -1,99 +0,0 @@
-import "./parent-style.css";
-
-let isIframeLoaded = false;
-const parentHostRoot = (document.querySelector("#chatterbox-script") as HTMLScriptElement).src;
-const parentHosRootURL = new URL(parentHostRoot);
-const hostRoot = `${parentHosRootURL.protocol}${parentHosRootURL.host}`;
-
-const sizeCollection = {
-    "desktop": {
-        "account-setup": { height: "334px", width: "375px" },
-        "timeline": {height: "595px", width: "375px"}
-    },
-    "mobile": {
-        "account-setup": { height: "100vh", width: "100vw" },
-        "timeline": {height: "100vh", width: "100vw"}
-    }
-}
-
-window.addEventListener("message", event => {
-    const { action } = event.data;
-    switch (action) {
-        case "resize-iframe":
-            resizeIframe(event.data);
-            break;
-        case "minimize":
-            minimizeIframe();
-            break;
-    }
-});
-
-function isMobile() {
-    return window.innerWidth <= 800 && window.innerHeight <= 930;
-}
-
-function renderStartButton() {
-    loadCSS();
-    const container = document.createElement("div");
-    container.className = "start";
-    const button = document.createElement("button");
-    button.className = "start-chat-btn";
-    button.onclick = () => isIframeLoaded? minimizeIframe() : loadChatterboxIframe();
-    container.appendChild(button);
-    document.body.appendChild(container);
-}
-
-function loadCSS() {
-    const linkElement = document.createElement("link") as HTMLLinkElement;
-    linkElement.rel = "stylesheet";
-    linkElement.href = new URL("CSS_FILE_NAME", parentHostRoot).href;
-    document.head.appendChild(linkElement);
-}
-
-function loadChatterboxIframe() {
-    const iframe = document.createElement("iframe");
-    const configLocation = (window as any).CHATTERBOX_CONFIG_LOCATION;
-    if (!configLocation) {
-        throw new Error("CHATTERBOX_CONFIG_LOCATION is not set");
-    }
-    iframe.src = new URL("../chatterbox.html?config=" + configLocation, hostRoot).href;
-    iframe.className = "chatterbox-iframe";
-    document.body.appendChild(iframe);
-    isIframeLoaded = true;
-    document.querySelector(".start-chat-btn").classList.add("start-background-minimized");
-    if (isMobile()) {
-        (document.querySelector(".start") as HTMLDivElement).style.display = "none";
-    }
-}
-
-function minimizeIframe() {
-    const iframeElement = document.querySelector(".chatterbox-iframe") as HTMLIFrameElement;
-    const startButtonDiv = document.querySelector(".start") as HTMLDivElement;
-    if (iframeElement.style.display !== "none") {
-        iframeElement.style.display = "none";
-        document.querySelector(".start-chat-btn").classList.remove("start-background-minimized");
-        if (isMobile()) {
-            startButtonDiv.style.display = "block";
-        }
-    }
-    else {
-        iframeElement.style.display = "block";
-        document.querySelector(".start-chat-btn").classList.add("start-background-minimized");
-        if (isMobile()) {
-            startButtonDiv.style.display = "none";
-        }
-    }
-}
-
-function resizeIframe(data) {
-    const { view } = data;
-    const type = isMobile()? "mobile": "desktop";
-    const size = sizeCollection[type][view];
-    if (!size) { return; }
-    const { height, width } = size;
-    const iframeElement = document.querySelector(".chatterbox-iframe") as HTMLIFrameElement;
-    if (height) { iframeElement.style.height = height; }
-    if (width) { iframeElement.style.width = width; }
-}
-
-renderStartButton();
diff --git a/src/parent/common.ts b/src/parent/common.ts
new file mode 100644
index 0000000000000000000000000000000000000000..4e67e073103a1cecc04309806d4cda5025233e21
--- /dev/null
+++ b/src/parent/common.ts
@@ -0,0 +1,3 @@
+export function isMobile() {
+    return window.innerWidth <= 800 && window.innerHeight <= 930;
+}
diff --git a/src/parent/iframe.ts b/src/parent/iframe.ts
new file mode 100644
index 0000000000000000000000000000000000000000..28880132b3440415a843c4e125475befcc96c657
--- /dev/null
+++ b/src/parent/iframe.ts
@@ -0,0 +1,42 @@
+import { isMobile } from "./common";
+
+const sizeCollection = {
+    "desktop": {
+        "account-setup": { height: "334px", width: "375px" },
+        "timeline": {height: "595px", width: "375px"}
+    },
+    "mobile": {
+        "account-setup": { height: "100vh", width: "100vw" },
+        "timeline": {height: "100vh", width: "100vw"}
+    }
+}
+
+export function toggleIframe() {
+    const iframeElement = document.querySelector(".chatterbox-iframe") as HTMLIFrameElement;
+    const startButtonDiv = document.querySelector(".start") as HTMLDivElement;
+    if (iframeElement.style.display !== "none") {
+        iframeElement.style.display = "none";
+        document.querySelector(".start-chat-btn").classList.remove("start-background-minimized");
+        if (isMobile()) {
+            startButtonDiv.style.display = "block";
+        }
+    }
+    else {
+        iframeElement.style.display = "block";
+        document.querySelector(".start-chat-btn").classList.add("start-background-minimized");
+        if (isMobile()) {
+            startButtonDiv.style.display = "none";
+        }
+    }
+}
+
+export function resizeIframe(data) {
+    const { view } = data;
+    const type = isMobile()? "mobile": "desktop";
+    const size = sizeCollection[type][view];
+    if (!size) { return; }
+    const { height, width } = size;
+    const iframeElement = document.querySelector(".chatterbox-iframe") as HTMLIFrameElement;
+    if (height) { iframeElement.style.height = height; }
+    if (width) { iframeElement.style.width = width; }
+}
diff --git a/src/parent/load.ts b/src/parent/load.ts
new file mode 100644
index 0000000000000000000000000000000000000000..a4ec55526aaa067331ceaa02d7e333a4e3e4d3fd
--- /dev/null
+++ b/src/parent/load.ts
@@ -0,0 +1,45 @@
+import { isMobile } from "./common";
+import { toggleIframe } from "./iframe";
+
+const parentHostRoot = ( document.querySelector("#chatterbox-script") as HTMLScriptElement).src;
+const hostRoot = new URL(parentHostRoot).origin;
+
+export function loadStartButton() {
+    loadCSS();
+    const container = document.createElement("div");
+    container.className = "start";
+    const button = document.createElement("button");
+    button.className = "start-chat-btn";
+    button.onclick = () => (window as any).isIframeLoaded? toggleIframe() : loadIframe();
+    container.appendChild(button);
+    document.body.appendChild(container);
+}
+
+function loadCSS() {
+    const linkElement = document.createElement("link") as HTMLLinkElement;
+    linkElement.rel = "stylesheet";
+    linkElement.href = new URL("CSS_FILE_NAME", parentHostRoot).href;
+    document.head.appendChild(linkElement);
+}
+
+function loadIframe() {
+    const iframe = document.createElement("iframe");
+    const configLocation = (window as any).CHATTERBOX_CONFIG_LOCATION;
+    if (!configLocation) {
+        throw new Error("CHATTERBOX_CONFIG_LOCATION is not set");
+    }
+    iframe.src = new URL(
+        "../chatterbox.html?config=" + configLocation,
+        hostRoot
+    ).href;
+    iframe.className = "chatterbox-iframe";
+    document.body.appendChild(iframe);
+    (window as any).isIframeLoaded = true;
+    document
+        .querySelector(".start-chat-btn")
+        .classList.add("start-background-minimized");
+    if (isMobile()) {
+        (document.querySelector(".start") as HTMLDivElement).style.display =
+            "none";
+    }
+}
diff --git a/src/parent-style.css b/src/parent/parent-style.css
similarity index 75%
rename from src/parent-style.css
rename to src/parent/parent-style.css
index 7dfe7077144711f3c99bae7fbbc739fb2892c747..a6eaa88954bde09942c8136bfc8c26a8a77fed01 100644
--- a/src/parent-style.css
+++ b/src/parent/parent-style.css
@@ -32,10 +32,10 @@
     border: none;
     border-radius: 100%;
     cursor: pointer;
-    background: no-repeat center url('./ui/res/chat-bubbles.svg'), linear-gradient(180deg, #7657F2 0%, #5C56F5 100%);
+    background: no-repeat center url('../ui/res/chat-bubbles.svg'), linear-gradient(180deg, #7657F2 0%, #5C56F5 100%);
     box-shadow: 0px 1px 3px rgba(0, 0, 0, 0.1), 0px 12px 32px -2px rgba(0, 0, 0, 0.2);
 }
 
 .start-background-minimized {
-    background: no-repeat center url("./ui/res/chevron-down-button.svg"), linear-gradient(180deg, #7657F2 0%, #5C56F5 100%);
+    background: no-repeat center url("../ui/res/chevron-down-button.svg"), linear-gradient(180deg, #7657F2 0%, #5C56F5 100%);
 }
diff --git a/src/parent/parent.ts b/src/parent/parent.ts
new file mode 100644
index 0000000000000000000000000000000000000000..ab7b50725fe6bc9d89314920365a2c521b941a11
--- /dev/null
+++ b/src/parent/parent.ts
@@ -0,0 +1,19 @@
+import { resizeIframe, toggleIframe } from "./iframe";
+import { loadStartButton } from "./load";
+import "./parent-style.css";
+
+(window as any).isIframeLoaded = false;
+
+window.addEventListener("message", event => {
+    const { action } = event.data;
+    switch (action) {
+        case "resize-iframe":
+            resizeIframe(event.data);
+            break;
+        case "minimize":
+            toggleIframe();
+            break;
+    }
+});
+
+loadStartButton();
diff --git a/src/ui/res/matrix-logo.svg b/src/ui/res/matrix-logo.svg
deleted file mode 100644
index d24a42875608d83db7066b3d6c2b57c21db22f94..0000000000000000000000000000000000000000
--- a/src/ui/res/matrix-logo.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="75" height="32" xmlns="http://www.w3.org/2000/svg">
-  <g fill="#9b9797" fill-rule="nonzero">
-    <path d="M.936.732V31.25H3.13v.732H.095V0h3.034v.732zM9.386 10.407v1.544h.044a4.461 4.461 0 0 1 1.487-1.368c.58-.323 1.245-.485 1.993-.485.72 0 1.377.14 1.972.42.595.279 1.047.771 1.355 1.477.338-.5.796-.941 1.377-1.323.58-.383 1.266-.574 2.06-.574.602 0 1.16.074 1.674.22.514.148.954.383 1.322.707.366.323.653.746.859 1.268.205.522.308 1.15.308 1.887v7.633H20.71v-6.464c0-.383-.015-.743-.044-1.082a2.305 2.305 0 0 0-.242-.882 1.473 1.473 0 0 0-.584-.596c-.257-.146-.606-.22-1.047-.22-.44 0-.796.085-1.068.253-.272.17-.485.39-.639.662a2.654 2.654 0 0 0-.308.927 7.074 7.074 0 0 0-.078 1.048v6.354h-3.128v-6.398c0-.338-.007-.673-.021-1.004a2.825 2.825 0 0 0-.188-.916 1.411 1.411 0 0 0-.55-.673c-.258-.168-.636-.253-1.135-.253a2.33 2.33 0 0 0-.584.1 1.94 1.94 0 0 0-.705.374c-.228.184-.422.449-.584.794-.161.346-.242.798-.242 1.357v6.619H6.434V10.407h2.952zM25.842 12.084a3.751 3.751 0 0 1 1.233-1.17 5.37 5.37 0 0 1 1.685-.629 9.579 9.579 0 0 1 1.884-.187c.573 0 1.153.04 1.74.121.588.081 1.124.24 1.609.475.484.235.88.562 1.19.981.308.42.462.975.462 1.666v5.934c0 .516.03 1.008.088 1.478.058.471.161.824.308 1.06H32.87a4.435 4.435 0 0 1-.22-1.104c-.5.515-1.087.876-1.762 1.081a7.084 7.084 0 0 1-2.071.31c-.544 0-1.05-.067-1.52-.2a3.472 3.472 0 0 1-1.234-.617 2.87 2.87 0 0 1-.826-1.059c-.199-.426-.298-.934-.298-1.522 0-.647.114-1.18.342-1.6.227-.419.52-.753.881-1.004.36-.25.771-.437 1.234-.562.462-.125.929-.224 1.399-.298.47-.073.932-.132 1.387-.176.456-.044.86-.11 1.212-.199.353-.088.631-.217.837-.386.206-.169.301-.415.287-.74 0-.337-.055-.606-.166-.804a1.217 1.217 0 0 0-.44-.464 1.737 1.737 0 0 0-.639-.22 5.292 5.292 0 0 0-.782-.055c-.617 0-1.101.132-1.454.397-.352.264-.558.706-.617 1.323h-3.128c.044-.735.227-1.345.55-1.83zm6.179 4.423a5.095 5.095 0 0 1-.639.165 9.68 9.68 0 0 1-.716.11c-.25.03-.5.067-.749.11a5.616 5.616 0 0 0-.694.177 2.057 2.057 0 0 0-.594.298c-.17.125-.305.284-.408.474-.103.192-.154.434-.154.728 0 .28.051.515.154.706.103.192.242.342.419.453.176.11.381.187.617.231.234.044.477.066.726.066.617 0 1.094-.102 1.432-.309.338-.205.587-.452.75-.739.16-.286.26-.576.297-.87.036-.295.055-.53.055-.707v-1.17a1.4 1.4 0 0 1-.496.277zM43.884 10.407v2.096h-2.291v5.647c0 .53.088.883.264 1.059.176.177.529.265 1.057.265.177 0 .345-.007.507-.022.161-.015.316-.037.463-.066v2.426a7.49 7.49 0 0 1-.882.089 21.67 21.67 0 0 1-.947.022c-.484 0-.944-.034-1.377-.1a3.233 3.233 0 0 1-1.145-.386 2.04 2.04 0 0 1-.782-.816c-.191-.353-.287-.816-.287-1.39v-6.728H36.57v-2.096h1.894v-3.42h3.129v3.42h2.29zM48.355 10.407v2.118h.044a3.907 3.907 0 0 1 1.454-1.754 4.213 4.213 0 0 1 1.036-.497 3.734 3.734 0 0 1 1.145-.176c.206 0 .433.037.683.11v2.912a5.862 5.862 0 0 0-.528-.077 5.566 5.566 0 0 0-.595-.033c-.573 0-1.058.096-1.454.287a2.52 2.52 0 0 0-.958.783 3.143 3.143 0 0 0-.518 1.158 6.32 6.32 0 0 0-.154 1.434v5.14h-3.128V10.407h2.973zM54.039 8.642V6.06h3.128v2.582H54.04zm3.128 1.765v11.405H54.04V10.407h3.128zM58.797 10.407h3.569l2.005 2.978 1.982-2.978h3.459l-3.745 5.339 4.208 6.067h-3.57l-2.378-3.596-2.38 3.596h-3.502l4.097-6.001zM74.094 31.25V.732H71.9V0h3.035v31.982H71.9v-.732z"/>
-  </g>
-</svg>