diff --git a/public_html/index.html b/public_html/index.html
index d6626527b5e4c0bb518e4d7d0e303ca1cfa98d92..f44938ba16948530659d511c2779f5d3ac57b6ed 100644
--- a/public_html/index.html
+++ b/public_html/index.html
@@ -1,28 +1,29 @@
 <!DOCTYPE html>
 <html>
 <head>
-<title>Dashboard</title>
-<meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
-<meta http-equiv="refresh" content="3600">
-
-<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
-<link rel="stylesheet" href="main.css">
+    <title>Dashboard</title>
+    <meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
+    <meta http-equiv="refresh" content="3600">
 
+    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
+    <link rel="stylesheet" href="main.css">
+</head>
 <body>
-    <header>
-        <h1>📋 Appmonitor dashboard</h1>
-    </header>
+    <div id="main">
+
+        <header>
+            <h1><span>📋</span> Appmonitor Dashboard</h1>
+        </header>
 
-    <section id="tag-section"><h2>🕛 fetching...</h2></section>
-    <section id="app-section"><h2>🕛 fetching...</h2></section>
+        <section id="tag-section"><h2><span>🕛</span> fetching...</h2></section>
+        <section id="app-section"><h2><span>🕛</span> fetching...</h2></setion></span>
 
-    <!--
-    <section id="msg-section"><h2>🛎️ Messages (coming soon)</h2></section>
-    -->
-    <br><br><br><br>
+    </div>
 
     <footer>
-        POC :: &copy; IML 2022
+        POC :: &copy; IML 2022 |
+        Sources: <a href="https://git-repo.iml.unibe.ch/iml-open-source/appmonitor-dashboard/" target="_blank">Appmonitor-dashboard</a> |
+        <a href="https://github.com/iml-it/appmonitor" target="_blank">Appmonitor</a>
     </footer>
 
     <script src="javascript/inc_config.js" type="text/javascript"></script>
diff --git a/public_html/javascript/functions.js b/public_html/javascript/functions.js
index cb4db7975a22cea2edb75dfaa990d7cc6c1e823e..a2a6068efa7a1d80bceedcd51f9204b5ab2d43fa 100644
--- a/public_html/javascript/functions.js
+++ b/public_html/javascript/functions.js
@@ -24,17 +24,26 @@ const ID_TAGINPUT='E_TAGS';
 // ----------------------------------------------------------------------
 
 var AM_TAGURL=false;
+var AM_PRETTYURL=false;
+var AM_TIMER=false;
 
 // ----------------------------------------------------------------------
 // FUNCTIONS
 // ----------------------------------------------------------------------
 
+function _getAMApiUrl(sPath){
+    return AM_PRETTYURL 
+        ? AM_SERVER_URL+sPath
+        : AM_SERVER_URL+'/index.php?request='+sPath
+    ;
+}
+
 /**
  * get url to fetch the tags
  * @returns string
  */
 function _getUrlForTags(){
-    return AM_SERVER_URL+'/v1/apps/tags';
+    return  _getAMApiUrl('/v1/apps/tags');
 }
 
 /**
@@ -43,8 +52,8 @@ function _getUrlForTags(){
  * @returns 
  */
 function _getUrlWithTags(tags){
-    return AM_SERVER_URL+'/v1/apps/tags/'+tags+'/all';
-}
+    return  _getAMApiUrl('/v1/apps/tags/'+tags+'/all');
+    }
 
 /**
  * helper: get a table row with data of an application
@@ -70,9 +79,18 @@ function _2digits(i){
 // ----------------------------------------------------------------------
 
 
-function tagAdd(tagname){
+function tagToggle(tagname){
     var o=document.getElementById(ID_TAGINPUT);
-    o.value+=(o.value ? "," : "") +tagname;
+    var s=o.value;
+    var re = new RegExp(",*"+tagname);
+    var s2=s.replace(re, "");
+    if(s2!==s) {
+        s=s.replace(re, "")
+        s=s.replace(/^,/, "");
+    } else {
+        s+=(s ? "," : "" ) + tagname;
+    }
+    o.value=s;
     getAppstatus();
 }
 
@@ -92,18 +110,17 @@ function _getTaglist(sData){
     var sTags='';
     let aData=JSON.parse(sData);
 
-    sReturn+='<input id="'+ID_TAGINPUT+'" type="text" size="50" value="'+AM_TAGS+'"'
-            +' onchange="getAppstatus()"'
+    sReturn+='<input id="'+ID_TAGINPUT+'" type="text" size="20" value="'+AM_TAGS+'"'
             +' onkeypress="getAppstatus()"'
             +' onkeydown="getAppstatus()"'
             +' onkeyup="getAppstatus()"'
         +'>'
-        +'<button onclick="tagClear();return false;"> ❌ </button><br><br>'
+        +'<button onclick="tagClear();return false;"> ❌ </button><br>'
         ;
 
     for (var s in aData['tags']){
         sTags+=(sTags ? ",": "") + aData['tags'][s];
-        sReturn+='<button onclick="tagAdd(\''+aData['tags'][s]+'\'); return false;">'+aData['tags'][s]+'</button>'
+        sReturn+='<button onclick="tagToggle(\''+aData['tags'][s]+'\'); return false;">'+aData['tags'][s]+'</button>'
     }
     return sReturn;
 }
@@ -115,21 +132,27 @@ function _getTaglist(sData){
  * called from getAppstatus
  */
  async function getTags(){
-    let out = '<h2>🏷️ Tags</h2>';
+    let out = '<h2><span>🏷️</span> Tags</h2>';
     AM_TAGURL=_getUrlForTags();
 
-    let response = await fetch(AM_TAGURL);
-    if (response.ok) {
-        out+=_getTaglist(await response.text());
-    } else {
-        out+='<div class="app result1">'
-            +'ERROR '+response.status+': '+response.statusText + ' - '
-            +AM_TAGURL
-            +'</div>';
-    } 
+    try{
+        let response = await fetch(AM_TAGURL);
+        if (response.ok) {
+            out+=_getTaglist(await response.text());
+        } else {
+            out+='<div class="app result1">'
+                +'ERROR '+response.status+': '+response.statusText + ' - '
+                +AM_TAGURL
+                +'</div>';
+        } 
+    } catch {
+        out+='<div class="app result3">'
+        +'ERROR: no response from '
+        +AM_TAGURL
+        +'</div>';
+    }
     
-    o=document.getElementById(OUT_ID_TAGS);
-    o.innerHTML=out;
+    o=document.getElementById(OUT_ID_TAGS).innerHTML=out;
 }
 
 
@@ -225,11 +248,12 @@ async function getAppstatus(){
     var o=document.getElementById(ID_TAGINPUT);
     tags=o ? o.value : AM_TAGS;
 
-    let out = '<h2>📦 Applications</h2>';
+    let out = '<h2><span>📦</span> Applications</h2>';
     // for (var i=0; i<AM_TAGS.length; i++){
 
         // let apiurl=_getUrlWithTags(AM_TAGS[i])
-        let apiurl=_getUrlWithTags(tags)
+    let apiurl=_getUrlWithTags(tags)
+    try{
         let response = await fetch(apiurl);
         if (response.ok) {
             out+=_getAllAppsStatus(await response.text());
@@ -239,10 +263,17 @@ async function getAppstatus(){
                 +apiurl
                 +'</div>';
         } 
+    }
+    catch {
+        out+='<div class="app result3">'
+        +'ERROR: no response from '
+        +apiurl
+        +'</div>';
+    }
     // }
-    o=document.getElementById(OUT_ID_APPS);
-    o.innerHTML=out;
-    window.setTimeout("getAppstatus()", REFRESHTIME*1000);
+    document.getElementById(OUT_ID_APPS).innerHTML=out;
+    clearTimeout(AM_TIMER);
+    AM_TIMER=window.setTimeout("getAppstatus()", REFRESHTIME*1000);
 }
 
 
@@ -250,8 +281,7 @@ async function getAppstatus(){
 // MAIN
 // ----------------------------------------------------------------------
 
+AM_TIMER=window.setTimeout("getAppstatus()", 500);
 
-window.setTimeout("getAppstatus()", 500);
 
-
-// ----------------------------------------------------------------------
+// ----------------------------------------------------------------------
\ No newline at end of file
diff --git a/public_html/main.css b/public_html/main.css
index 6f5184206174647c6f4763286d30e3f8c708fe67..878e0a8542bd04de2d3c7109d075bbe3823a60d2 100644
--- a/public_html/main.css
+++ b/public_html/main.css
@@ -4,10 +4,11 @@
     --color-0: #345;
     --color-h1: #c54;
     --color-h2: #569;
-    --color-links: #8ae;
+    --color-links: #349;
 
-    --color-result-0: 
-    --bg-0: #f8f8f8;
+    --bg-0: #ddd;
+    --bg-main: #fff;
+    --bg-footer: #ccd;
 }
 
 
@@ -20,17 +21,18 @@ body{
     font-family: verdana,arial;
 }
 
-button{ border:1px solid #ccc; background: linear-gradient(#f8f8f8, #eee); border-radius: 0.3em; margin: 0 0.5em 0.5em 0; padding: 0.5em;}
+button{ border: 1px solid  rgba(0,0,0,0.05); background: linear-gradient(#f8f8f8, #eee); border-radius: 0.3em; margin: 0 0.5em 0.5em 0; padding: 0.5em;}
 button:hover{ background: linear-gradient(#eee, #ddd); border-radius: 0.3em; margin: 0 0.5em 0.5em 0; padding: 0.5em;}
 button:active{ border:1px solid #fc2;}
 input{ border:1px solid #ccc; padding: 0.4em;}
 
-footer{ position: fixed; bottom: 0; left: 0; width: 100%; padding: 1em; background: #eee; text-align: center;}
+footer{ position: fixed; bottom: 0; left: 0; width: 100%; padding: 1em; background: var(--bg-footer); text-align: center;}
 h1{color: var(--color-h1)}
 h2{color: var(--color-h2); margin-left: -1em;}
 
+h1>span, h2>span{font-size: 200%;}
 section{
-    margin: 2em 0;
+    margin: 0 0 2em ;
     padding: 0.2em 2em;
     border-top: 0px solid #abc;
     border-radius: 1em;
@@ -38,9 +40,19 @@ section{
 
 td{vertical-align: top;}
 
+#main{
+    background: var(--bg-main);
+    border: 3px solid #bbb;
+    border-radius: 1em;
+    box-shadow: 0 0 3em rgba(0,0,0,0.2);
+    margin: 1em 5% 6em;
+    padding: 1em;
+    min-height: 35em;
+}
+
 .app{
     margin: 1em 0;
-    border: 2px solid;
+    border: 0px solid rgba(0,0,0,0.2);
     border-radius: 0.3em;
     padding: 1em; 
 }