diff --git a/www/res/js/modules/locutus.js b/www/res/js/modules/locutus.js
index 91ba429..463e0b1 100644
--- a/www/res/js/modules/locutus.js
+++ b/www/res/js/modules/locutus.js
@@ -40,7 +40,6 @@ export class App {
     }
 
     handleHash(hash) {
-        console.log(hash);
         if (hash[0] === '#') hash = hash.substr(1);
 
         let defaultCase = () => {
@@ -81,19 +80,30 @@ export class App {
         //this.setHash(hash);
     }
 
-    login(accountName, domainName, password) {
-        return USIMP.Domain.fromName(domainName).then(domain => {
-            let session = new USIMP.Session(domain);
-            session.authenticate(accountName, password)
-                .catch((event) => {
-                    console.error(`Unable to reach domain server: ${event}`);
-                })
-                .then(() => {
-                    this.session = session;
-                    this.defaultLocation = "/";
-                    this.setHash("/");
-                });
-        });
+    async login(accountName, domainName, password) {
+        let domain;
+        try {
+            domain = await USIMP.Domain.fromName(domainName);
+        } catch (error) {
+            if (error instanceof DOMException) {
+                throw Error("Connection timed out");
+            } else {
+                throw Error("Invalid USIMP domain");
+            }
+        }
+
+        let session = new USIMP.Session(domain);
+        let rtt = await session.chooseDomainServer();
+        console.log(rtt);
+
+        let response = await session.authenticate(accountName, password);
+        if (response.status === "success") {
+            this.session = session;
+            this.defaultLocation = "/";
+            this.setHash("/");
+        } else {
+            throw Error(response.message);
+        }
     }
 
     hideMain() {
@@ -167,15 +177,19 @@ export class App {
                 form.appendChild(div);
             }
 
-            this.login(form.account.value, form.domain.value, form.password.value)
-                .catch(reason => {
+            try {
+                await this.login(form.account.value, form.domain.value, form.password.value);
+            } catch (error) {
+                if (error.toString() === "Error: unable to authenticate") {
+                    document.getElementsByName("account")[0].setAttribute("invalid", "invalid");
+                } else {
                     document.getElementsByName("domain")[0].setAttribute("invalid", "invalid");
-                    formError("Invalid USIMP domain");
-                    console.error(reason);
-                })
-                .finally(() => {
-                    for (let e of form) e.disabled = false;
-                });
+                }
+                formError(error.toString());
+                console.error(error);
+            } finally {
+                for (let e of form) e.disabled = false;
+            }
         });
 
         this.windows.appendChild(win);
@@ -184,6 +198,10 @@ export class App {
             event.target.removeAttribute("invalid");
         });
 
+        document.getElementsByName("account")[0].addEventListener("input", (event) => {
+            event.target.removeAttribute("invalid");
+        });
+
         document.getElementsByName("account")[0].focus();
     }
 
@@ -192,7 +210,7 @@ export class App {
             
`;
 
@@ -208,7 +226,7 @@ export class App {
         });
 
         this.session.subscribe(response => {
-            this.addMessage(response.event.data.message);
+            this.addMessage(response.data.event.data.message);
         });
     }
 }
diff --git a/www/res/js/modules/usimp.js b/www/res/js/modules/usimp.js
index bb9c87a..158218e 100644
--- a/www/res/js/modules/usimp.js
+++ b/www/res/js/modules/usimp.js
@@ -15,47 +15,51 @@ export class Domain {
         this.name = jsonData.name;
         this.id = jsonData.id;
         this.servers = [];
-        for (let domainServer of domainServers) {
+        for (const domainServer of domainServers) {
             this.servers.push(new DomainServer(domainServer));
         }
         this.invalidServers = [];
     }
 
     static async fromName(domainName) {
-        return fetch(`https://${domainName}/.well-known/usimp.json`, {
+        const controller = new AbortController();
+        const timer = setTimeout(() => controller.abort(), 2000);
+
+        let response = await fetch(`https://${domainName}/.well-known/usimp.json`, {
             redirect: "manual",
-        }).then(response => {
-            if (response.ok) {
-                return response.json();
-            } else {
-                throw "Invalid response";
-            }
-        }).then(data => {
-            return new Domain(data.domain, data.domain_servers);
+            signal: controller.signal,
         });
+
+        clearTimeout(timer);
+        if (!response.ok) {
+            throw Error("Invalid response");
+        }
+
+        const data = await response.json();
+        return new Domain(data.domain, data.domain_servers);
     }
 
     chooseDomainServer() {
         if (this.servers.length === 0) throw Error("No domain servers specified");
 
-        this.servers.filter(srv => this.invalidServers.map(srv => srv.id).includes(srv.id));
-        if (this.servers.length === 0) throw Error("No domain servers reachable");
-        if (this.servers.length === 1) return this.servers[0];
+        const servers = this.servers.filter(srv => !this.invalidServers.map(srv => srv.id).includes(srv.id));
+        if (servers.length === 0) throw Error("No domain servers reachable");
+        if (servers.length === 1) return servers[0];
 
-        let priority = this.servers.reduce((min, srv) => Math.min(min, srv.priority), Infinity);
-        let domainServers = this.servers.filter(srv => srv.priority === priority);
-        if (domainServers.length === 1) return this.servers[0];
+        const priority = servers.reduce((min, srv) => Math.min(min, srv.priority), Infinity);
+        const domainServers = servers.filter(srv => srv.priority === priority);
+        if (domainServers.length === 1) return servers[0];
 
-        let totalWeight = domainServers.reduce((total, srv) => total + srv.weight, 0);
-        let w = Math.floor(Math.random() * totalWeight);
+        const totalWeight = domainServers.reduce((total, srv) => total + srv.weight, 0);
+        const w = Math.floor(Math.random() * totalWeight);
 
         let accumulator = 0;
-        for (let srv of domainServers) {
+        for (const srv of domainServers) {
             accumulator += srv.weight;
             if (w < accumulator) return srv;
         }
 
-        throw "Domain server selection did not work correctly";
+        throw Error("Domain server selection did not work correctly");
     }
 }
 
@@ -107,37 +111,51 @@ export class Session {
 
     constructor(domain) {
         this.domain = domain;
-        this.server = domain.chooseDomainServer();
         this.numRequests = 0;
+    }
 
-        const host = this.server.host;
-        const protocols = this.server.protocols;
+    async chooseDomainServer() {
+        while (!this.server) {
+            this.server = this.domain.chooseDomainServer();
 
-        /*
-        if ("wss" in protocols) {
-            this.wsConnection = new WebSocket(`wss://${host}:${protocols.wss}/_usimp/websocket`, ["usimp"]);
-        } else if ("ws" in protocols) {
-            this.wsConnection = new WebSocket(`ws://${host}:${protocols.ws}/_usimp/websocket`, ["usimp"])
-        }
-        */
+            const host = this.server.host;
+            const protocols = this.server.protocols;
 
-        if ("https" in protocols) {
-            this.httpBaseUrl = `https://${host}:${protocols.https}/_usimp`;
-        } else if ("http" in protocols) {
-            this.httpBaseUrl = `http://${host}:${protocols.http}/_usimp`;
-        } else {
-            throw "Domain server provides no supported transport protocols";
+            /*
+            if ("wss" in protocols) {
+                this.wsConnection = new WebSocket(`wss://${host}:${protocols.wss}/_usimp/websocket`, ["usimp"]);
+            }
+            */
+
+            // TODO http -> https
+            if ("http" in protocols) {
+                this.httpBaseUrl = `http://${host}:${protocols.http}/_usimp`;
+                try {
+                    return await this.ping();
+                } catch {
+                    this.domain.invalidServers.push(this.server);
+                    this.server = null;
+                }
+            } else {
+                console.warn(`Domain server ${this.server} does not support 'https' transport protocol`);
+                this.domain.invalidServers.push(this.server);
+                this.server = null;
+            }
         }
     }
 
-    send(endpoint, data) {
+    async send(endpoint, data, timeout = 2000, forceHttp = false) {
         this.numRequests++;
-        if (this.wsConnection) {
+
+        if (!forceHttp && this.wsConnection) {
             this.wsConnection.send(JSON.stringify({
                 'request_num': this.numRequests,
                 'data': data
             }));
         } else {
+            const controller = new AbortController();
+            const timer = setTimeout(() => controller.abort(), timeout);
+
             let headers = {
                 'Content-Type': 'application/json',
                 'To-Domain': this.domain.id,
@@ -147,28 +165,45 @@ export class Session {
                 headers['Authorization'] = `usimp ${this.token}`;
             }
 
-            return fetch(`${this.httpBaseUrl}/${endpoint}`, {
+            const startTime = new Date();
+            let response = await fetch(`${this.httpBaseUrl}/${endpoint}`, {
                 method: "POST",
                 headers: headers,
                 body: JSON.stringify(data),
-            }).then(response => {
-                return response.json();
+                signal: controller.signal,
             });
+            const endTime = new Date();
+            clearTimeout(timer);
+
+            let responseData = await response.json();
+            responseData.duration = endTime - startTime;
+            return responseData;
         }
     }
 
-    authenticate(accountName, password) {
-        return this.send("authenticate", {
+    async ping() {
+        let result = {"http": null, "ws": null};
+        const res = await this.send("ping", {}, undefined, true);
+        result.http = res.duration;
+        if (this.wsConnection) {
+            await this.wsConnection.ping();
+        }
+        return result;
+    }
+
+    async authenticate(accountName, password) {
+        let response = await this.send("authenticate", {
             type: "password",
             name: accountName,
             password: password,
-        }).then(response => {
-            this.token = response.token;
-            return response;
         });
+        if (response.status === "success") {
+            this.token = response.data.token;
+        }
+        return response;
     }
 
-    sendEvent(roomId, data) {
+    async sendEvent(roomId, data) {
         return this.send("send_event", {
             room_id: roomId,
             data: data,
diff --git a/www/res/styles/styles.css b/www/res/styles/styles.css
index 9c9a091..8de3afd 100644
--- a/www/res/styles/styles.css
+++ b/www/res/styles/styles.css
@@ -54,7 +54,6 @@ div#windows {
 
 div#windows > *,
 main {
-    backdrop-filter: blur(32px);
     border: 1px solid var(--bg-win);
     background: var(--bg-win);
     border-radius: 4px;
@@ -68,6 +67,7 @@ main {
 }
 
 div#windows > * {
+    backdrop-filter: blur(32px);
     padding: 0.5em 1em;
 }
 
@@ -199,6 +199,7 @@ main .chat-history {
     height: calc(100% - 3em);
     overflow-y: scroll;
     box-sizing: border-box;
+    backdrop-filter: blur(4px);
 }
 
 main .chat-input-wrapper {
@@ -207,6 +208,7 @@ main .chat-input-wrapper {
     border-top: 1px solid var(--bg-win);
     padding: 0.5em 1em;
     box-sizing: border-box;
+    backdrop-filter: blur(32px);
 }
 
 main .chat-input-wrapper input {
@@ -218,6 +220,7 @@ main .chat-input-wrapper input {
     box-sizing: border-box;
     outline: none;
     padding: 0.25em 1em;
+    font-size: 0.875rem;
 }
 
 main .chat .message {
@@ -228,5 +231,6 @@ main .chat .message {
     display: block;
     width: fit-content;
     width: -moz-fit-content;
-    background-color: var(--bg);
+    background-color: rgba(255, 255, 255, 0.875);
+    font-size: 0.875rem;
 }