diff --git a/index.html b/index.html
index 24d9ca3480d2efb9e7c83097c25ff0d90d695f5d..04dd9ce02115b75e8d6fed99bb02e60a7bb1c571 100644
--- a/index.html
+++ b/index.html
@@ -11,7 +11,11 @@
   <body>
     <div id="app"></div>
     <div id="log"></div>
-    <button type="button" id="reload" onclick="window.location.reload()">Reload</button> 
+    <aside>
+      <!-- <button type="button" id="reload" onclick="window.location.reload()">
+        Reload
+      </button> -->
+    </aside>
     <script type="module" src="/src/main.js"></script>
   </body>
 </html>
diff --git a/src/main.js b/src/main.js
index 5983a4ef8745b3ca8ed1f9fe1e3bca729773a9d9..88e945e99c3258c6c71b37c68f02f20e4cd4f9ef 100644
--- a/src/main.js
+++ b/src/main.js
@@ -192,6 +192,9 @@ function buildPageContents(object) {
     const navigationEl = document.getElementById("navigation");
     navigationEl.replaceChildren(listEl);
 
+    // auto select first item
+    // focusNavigationItem(1);
+
     // build navigation item
     function buildNavigationItemEl(item) {
       const itemEl = document.createElement("li");
@@ -240,8 +243,10 @@ function navigateToSelected() {
   const currentItem = document.querySelector(
     "#navigation > ul > li[data-selected] a"
   );
-  const path = currentItem.getAttribute("href");
-  navigateToPath(path);
+  if (currentItem) {
+    const path = currentItem.getAttribute("href");
+    navigateToPath(path);
+  } else printLogMsg("no item selected to open");
 }
 
 // focus specific navigation item
@@ -339,21 +344,25 @@ function addButtonControls() {
   // add two button controls for menu
   document.addEventListener("keydown", onKeyDown);
 
+  window.addEventListener("volumechange", function (event) {
+    printLogMsg("Volume up button was pressed.");
+  });
+
   // on keydown event
   function onKeyDown(event) {
-
-    printLogMsg(event.code);
-
     // prevent defaults
     if (
       event.code === "Tab" ||
       event.code === "Enter" ||
       event.code === "Escape" ||
-      event.code === "ArrowDown" ||
       event.code === "ArrowUp" ||
-      event.code === "ArrowRight"
-    )
+      event.code === "ArrowRight" ||
+      event.code === "ArrowDown" ||
+      event.code === "ArrowLeft"
+    ) {
       event.preventDefault();
+      printLogMsg("key: " + event.code);
+    }
 
     // browsing navigation items
     if (event.code === "Tab" || event.code === "ArrowDown")
@@ -363,6 +372,7 @@ function addButtonControls() {
     else if (event.code === "ArrowRight") moveDownNavigationLevel();
     else if (event.code === "ArrowLeft" || event.code === "Escape")
       moveUpNavigationLevel();
+    else if (event.code === "VolumeUp") printLogMsg("yes");
   }
 
   console.log(navigator.mediaSession);
@@ -373,15 +383,93 @@ function addButtonControls() {
     logEl.innerHTML += "volumeup";
   });
 
-  // navigator.mediaSession.setActionHandler("volumedown", (event) => {
-  //   const logEl = document.getElementById("log");
-  //   logEl.innerHTML += "volumeup";
+  // const toggleButtonControlsEl = document.getElementById(
+  //   "toggle-button-controls"
+  // );
+
+  // toggleButtonControlsEl.addEventListener("click", (event) => {
+  //   const audioElement = document.createElement("audio");
+  //   const audioCtx = new AudioContext();
+  //   const source = audioCtx.createMediaElementSource(audioElement);
+  //   const gainNode = audioCtx.createGain();
+  //   source.connect(gainNode).connect(audioCtx.destination);
+
+  //   // Set the initial volume level
+  //   gainNode.gain.value = 0.2;
+  //   console.log(gainNode.gain.value);
+
+  // Adjust the volume when the device volume buttons are pressed
+  // document.addEventListener("keydown", (event) => {
+  //   if (event.key === "ArrowUp") {
+  //     printLogMsg("volume up");
+  //     gainNode.gain.value += 0.1;
+  //   } else if (event.key === "ArrowDown") {
+  //     printLogMsg("volume down");
+  //     gainNode.gain.value -= 0.1;
+  //   }
+  // });
   // });
 }
 
 // add voice controls
 // ===================
 function addVoiceControls() {
+  var SpeechRecognition = SpeechRecognition || webkitSpeechRecognition;
+  var SpeechGrammarList = SpeechGrammarList || window.webkitSpeechGrammarList;
+  var SpeechRecognitionEvent =
+    SpeechRecognitionEvent || webkitSpeechRecognitionEvent;
+
+  var commands = ["menu", "call", "check", "apps", "open", "back", "close", "exit"];
+
+  var recognition = new SpeechRecognition();
+  if (SpeechGrammarList) {
+    var speechRecognitionList = new SpeechGrammarList();
+    var grammar =
+      "#JSGF V1.0; grammar commands; public <command> = " +
+      commands.join(" | ") +
+      " ;";
+    speechRecognitionList.addFromString(grammar, 1);
+    recognition.grammars = speechRecognitionList;
+  }
+  recognition.continuous = false;
+  recognition.lang = "en-US";
+  recognition.interimResults = false;
+  recognition.maxAlternatives = 1;
+
+  recognition.start();
+  printLogMsg("recognition started");
+
+  recognition.onresult = function (event) {
+    let command = event.results[0][0].transcript;
+    let confidence = event.results[0][0].confidence;
+
+    if (commands.includes(command)) {
+      printLogMsg("Received: " + command + ". Confidence: " + confidence);
+
+      if (command === "menu") navigateToPath("/menu");
+      else if (command === "call") navigateToPath("/menu/call");
+      else if (command === "check") navigateToPath("/menu/check");
+      else if (command === "apps") navigateToPath("/menu/apps");
+      else if (command === "open") navigateToSelected();
+      else if (command === "back" || command === "close")
+        moveUpNavigationLevel();
+      else if (command === "exit") navigateToPath("/");
+    }
+  };
+
+  recognition.onspeechend = function () {
+    recognition.stop();
+    printLogMsg("recognition stopped");
+
+    setTimeout(() => {
+      recognition.start();
+      printLogMsg("recognition started");
+    }, "1000");
+  };
+
+  recognition.onnomatch = function (event) {
+    printLogMsg("I didn't recognise that command.");
+  };
 }
 
 // printing messages on screen for debugging
@@ -389,7 +477,7 @@ function printLogMsg(message) {
   const logEl = document.getElementById("log");
   logEl.innerHTML += `${message}<br>`;
   logEl.scrollTop = logEl.scrollHeight;
-  console.debug(message);
+  console.log(message);
 }
 
 init();
diff --git a/src/styles/main.css b/src/styles/main.css
index 71b885ccf41454000db7145064584034d8c26193..4642fd3ce65bd7030d901d445887c65b6f3830b3 100644
--- a/src/styles/main.css
+++ b/src/styles/main.css
@@ -32,17 +32,19 @@ a {
 .link[data-selected] a {
   border-color: var(--color-white);
 }
-#reload {
+aside {
+  display: flex;
+  flex-direction: column;
   position: absolute;
   top: 0;
-  left: 0;
+  right: 0;
 }
 #log {
-  color: red;
-  text-align: right;
+  color: hsl(0, 100%, 30%);
   position: absolute;
+  font: normal 0.6em/1.2em sans-serif;
   top: 0;
-  right: 0;
+  left: 0;
   max-height: 20vh;
   z-index: 100;
   padding: 1em;
diff --git a/src/styles/main.less b/src/styles/main.less
index 527be6ec535798ee7c83deed232643e765ee4ea9..b6b57a0a75f09c48cc49f9e7672760b69697d07c 100644
--- a/src/styles/main.less
+++ b/src/styles/main.less
@@ -41,18 +41,20 @@ a {
   }
 }
 
-#reload {
+aside {
+  display: flex;
+  flex-direction: column;
   position: absolute;
   top: 0;
-  left: 0;
+  right: 0;
 }
 
 #log {
-  color: red;
-  text-align: right;
+  color: hsl(0 100% 30%);
   position: absolute;
+  font: normal .6em/1.2em sans-serif;
   top: 0;
-  right: 0;
+  left: 0;
   max-height: 20vh;
   z-index: 100;
   padding: 1em;