diff --git a/classes/cronlog-renderer.class.php b/classes/cronlog-renderer.class.php
index 9f6e0580aaa9802c4f4358ac21102832bffee178..b49548023628bfa707d0d92b143e4236772ada05 100644
--- a/classes/cronlog-renderer.class.php
+++ b/classes/cronlog-renderer.class.php
@@ -244,11 +244,13 @@ class cronlogrenderer extends cronlog{
         }
         $sReturn='';
         $sServer=isset($_SERVER['SERVER_NAME']) ? $_SERVER['SERVER_NAME'] : false;
+        $sReturn.='<li class="nav-item d-none d-sm-inline-block"><a href="#" class="nav-link">Instances:</a></li>';
         
         foreach($this->_aInstances as $sInstance => $sUrl){
             $sHost=parse_url($sUrl, PHP_URL_HOST);
-            $sClass=($sServer && $sServer==$sHost) ? 'active' : '';
-            $sReturn.='<a class="'.$sClass.'" href="'.$sUrl.'" title="'.$sUrl.'">'.$sInstance.'</a> ';
+            $sClass=($sServer && $sServer==$sHost) ? 'active bg-gray' : '';
+            // $sReturn.='<a class="'.$sClass.'" href="'.$sUrl.'" title="'.$sUrl.'">'.$sInstance.'</a> ';
+            $sReturn.='<li class="nav-item d-none d-sm-inline-block '.$sClass.'"><a href="'.$sUrl.'" class="nav-link">'.$sInstance.'</a></li>';
         }
         return $sReturn;
     }
@@ -494,7 +496,7 @@ class cronlogrenderer extends cronlog{
     */
    public function renderLogfile($sLogfile){
         $sHtml=''
-                . '<button style="position: fixed;" onclick="closeOverlay();"><i class="fas fa-chevron-left"></i> back</button><br><br>'
+                . '<button style="position: fixed;" onclick="closeOverlay();" class="btn btn-default"><i class="fas fa-chevron-left"></i> back</button><br><br>'
                 . '<h3>Logfile '.basename($sLogfile).'</h3>'
                 ;
         if(!$sLogfile){
@@ -561,11 +563,14 @@ class cronlogrenderer extends cronlog{
                     .'>'.$sServer.'</option>';
         }
         $sHtml=$sHtml 
-                ? '<input id="serverfiltertext" type="text" placeholder="filter server" value=""
+                ? ''
+                    /*
+                    .'<input id="serverfiltertext" type="text" placeholder="filter server" value=""
                     onchange="filterServers();"
                     onkeypress="filterServers();"
                     onkeyup="filterServers();"
                     ><button onclick="$(\'#serverfiltertext\').val(\'\'); filterServers();">X</button><br><br>'
+                    */
                     .'<select'
                     . ' size="'.( min(array(count($this->getServers())+1 , $iMaxItemsToShow)) ).'"'
                     // . ' size="1"'
diff --git a/classes/htmlelements.class.php b/classes/htmlelements.class.php
new file mode 100755
index 0000000000000000000000000000000000000000..91943c7c97d4a3226b6a2c457496ed85b08ef447
--- /dev/null
+++ b/classes/htmlelements.class.php
@@ -0,0 +1,222 @@
+<?php
+
+/**
+ * Generator for HTML Tags
+ * 
+ * see getTag() ... 
+ *    it generates html code for tags 
+ *    - with and without label
+ *    - with and without closing tag
+ * 
+ * see _setAttributes($aAttributes) ... 
+ *    attribute will be inserted with given key-value array
+ *    BUT with special attribute keys:
+ *    - label - will be used as label
+ *    - icon  - will be added as <i class="[icon value]"></i> to the label
+ * 
+ * @author Axel
+ */
+class htmlelements {
+
+    /**
+     * set of auto generated icon prefixes
+     * @var type 
+     */
+    var $_aIcons=array(
+            // 'fa-'=>'fa ',
+        );
+    
+    var $_sLabel = '';
+    var $_aAttributes = array();
+    
+
+    // ----------------------------------------------------------------------
+    // CONSTRUCTOR
+    // ----------------------------------------------------------------------
+    
+    public function __construct() {
+        return true;
+    }
+
+    // ----------------------------------------------------------------------
+    // 
+    // PRIVATE FUNCTIONS 
+    // 
+    // ----------------------------------------------------------------------
+    
+    
+    /**
+     * generate html attibutes with all internal attributes key -> values
+     * @return string
+     */
+    protected function _addAttributes() {
+        $sReturn = '';
+        foreach ($this->_aAttributes as $sAttr => $sValue) {
+            if(is_array($sValue)){
+                echo "ERROR: an html tag was defined with array in attribute [$sAttr]:<br><pre>".print_r($this->_aAttributes, 1)."</pre>";
+            }
+            $sReturn .= ' '.$sAttr . '="' . $sValue . '"';
+            
+        }
+        return $sReturn;
+    }
+    
+    
+    /**
+     * internal helper: fetch all attributes from key-value hash; 
+     * Specialties here:
+     * - label will be extracted from key 'label' 
+     * - and optional existing key 'icon' will be added at beginning of a label
+     * 
+     * @param array $aAttributes
+     * @return boolean
+     */
+    protected function _setAttributes($aAttributes){
+        $this->_sLabel='';
+        if(isset($aAttributes['icon']) && $aAttributes['icon']){
+            $this->_sLabel.=$this->getIcon($aAttributes['icon']);
+            unset($aAttributes['icon']);
+        }
+        if(isset($aAttributes['label']) && $aAttributes['label']){
+            $this->_sLabel .= $aAttributes['label'];
+            unset($aAttributes['label']);
+        }
+        $this->_aAttributes=$aAttributes;
+        return true;
+    }
+
+    // ----------------------------------------------------------------------
+    // 
+    // PUBLIC FUNCTIONS
+    // HTML GENERIC
+    // 
+    // ----------------------------------------------------------------------
+    
+    /**
+     * generic function to get html code for a single tag 
+     * 
+     * @param string   $sTag          tag name
+     * @param array    $aAttributes   array with attributes (optional including 'icon' and 'label')
+     * @param boolean  $bCloseTag     optional: set false if tag has no closing tag (= ending with "/>")
+     * @return type
+     */
+    public function getTag($sTag, $aAttributes, $bCloseTag=true){
+        $sTpl = $bCloseTag ? "<$sTag%s>%s</$sTag>" : "<$sTag %s/>%s";
+        $this->_setAttributes($aAttributes);
+        return sprintf($sTpl, $this->_addAttributes(), $this->_sLabel);
+    }
+    
+    // ----------------------------------------------------------------------
+    // 
+    // PUBLIC FUNCTIONS
+    // SIMPLE HTML ELEMENTS
+    // 
+    // ----------------------------------------------------------------------
+
+    /**
+     * helper detect prefix of a string add prefix of a framework
+     * i.e. value "fa-close" detects font awesome and adds "fa " as prefix
+     * 
+     * @param string $sIconclass
+     * @return boolean
+     */
+    public function getIcon($sIconclass=false){
+        if(!$sIconclass){
+            return '';
+        }
+        $sPrefix='';
+        foreach ($this->_aIcons as $sPrefix =>$add) {
+            if (strpos($sIconclass, $sPrefix)===0){
+                $sPrefix=$add;
+                continue;
+            }
+        }
+        // do not use this .. it overrides internal attribute vars
+        // return $this->getTag('i', array('class'=>$sPrefix.$sIconclass));
+        return '<i class="'.$sPrefix.$sIconclass.'"></i> ';
+    }
+   
+
+    // ----------------------------------------------------------------------
+    // 
+    // PUBLIC FUNCTIONS
+    // HTML COMPONENTS
+    // 
+    // ----------------------------------------------------------------------
+
+    /**
+     * get html code for an input field
+     * 
+     * @param array $aAttributes  attributes of the select tag
+     * @return string
+     */
+    public function getFormInput($aAttributes){
+        $sTpl = '<input %s/>';
+        $this->_setAttributes($aAttributes);
+        return sprintf($sTpl, $this->_addAttributes());
+    }
+    /**
+     * get html code for an option field in a select drop down
+     * 
+     * @param array $aAttributes  attributes of the option tag
+     * @return string
+     */
+    public function getFormOption($aAttributes){
+        $sTpl = '<option %s>%s</option>';
+        $this->_setAttributes($aAttributes);
+        return sprintf($sTpl, $this->_addAttributes(), $this->_sLabel);
+    }
+    /**
+     * get html code for a select drop down
+     * 
+     * @param array $aAttributes  attributes of the select tag
+     * @param array $aOptions     array for all option fields
+     * @return string
+     */
+    public function getFormSelect($aAttributes, $aOptions=array()){
+        // $sTpl = '<select %s>%s</select>';
+
+        if(!count($aOptions)){
+            return false;
+        }
+        $sOptions='';
+        foreach($aOptions as $aOptionAttributes){
+            // $sOptions.=$this->getFormOption($aOptionAttributes);
+            $sOptions.=$this->getTag('option', $aOptionAttributes);
+        }
+        $aAttributes['label']=$sOptions;
+        return $this->getTag('select', $aAttributes);
+        /*
+        $this->_setAttributes($aAttributes);
+        return sprintf($sTpl, $this->_addAttributes(), $sOptions);
+         * 
+         */
+    }
+
+    public function getTable($aHead, $aBody, $aTableAttributes=array()){
+        $sReturn='';
+        $sTdata='';
+        $sThead='';
+        $sTpl = '<table %s>'
+                . '<thead><tr>%s</tr></thead>'
+                . '<tbody>%s</tbody>'
+                . '</table>';
+        
+        foreach($aHead as $sTh){
+            $sThead.='<th>'.$sTh.'</th>';
+        }
+        foreach($aBody as $aTr){
+            $sTdata.='<tr>';
+            foreach($aTr as $sTd){
+                $sTdata.='<td>'.$sTd.'</td>';
+            }
+            $sTdata.='</tr>';
+        }
+        $this->_setAttributes($aTableAttributes);
+        return sprintf($sTpl, 
+                $this->_addAttributes(), 
+                $sThead,
+                $sTdata
+                );
+    }
+}
diff --git a/classes/render-adminlte.class.php b/classes/render-adminlte.class.php
new file mode 100755
index 0000000000000000000000000000000000000000..0f25163c89698484a71b800007d0633e8fbf0991
--- /dev/null
+++ b/classes/render-adminlte.class.php
@@ -0,0 +1,1138 @@
+<?php
+require_once 'htmlelements.class.php';
+/**
+ * ======================================================================
+ * 
+ * RENDERER FOR ADNINLTE template https://adminlte.io
+ * DOCS: https://adminlte.io/docs/3.2/
+ *       https://adminlte.io/themes/v3/index3.html
+ * 
+ * ======================================================================
+ *
+ * @author Axel
+ */
+class renderadminlte {
+
+    var $aPresets=[
+
+        'bgcolor'=>[
+            'description'=>'background colors',
+            'group'=>'styling',
+            'values'=>[
+                // https://adminlte.io/themes/v3/pages/UI/general.html
+                ''=>'no value',
+                'indigo'=>'indigo',
+                'lightblue'=>'',
+                'navy'=>'',
+                'purple'=>'',
+                'fuchsia'=>'',
+                'pink'=>'',
+                'maroon'=>'',
+                'orange'=>'',
+                'lime'=>'',
+                'teal'=>'',
+                'olive'=>'',
+        
+                'black'=>'black',
+                'dark'=>'dark gray',
+                'gray'=>'gray', 
+                'light'=>'light gray', 
+            ]
+        ],
+    
+        'type'=>[
+            'description'=>'type or status like info/ warning/ danger to define a color',
+            'group'=>'styling',
+            'values'=>[
+                ''=>'no value',
+                'danger'=>'red',
+                'info'=>'aqua',
+                'primary'=>'blue',
+                'secondary'=>'gray',
+                'success'=>'green',
+                'warning'=>'yellow',
+                'dark'=>'dark gray',
+                'gray'=>'gray', 
+            ]
+        ],
+        'shadow'=>[
+            'description'=>'use a shadow',
+            'group'=>'styling',
+            'values'=>[
+                ''=>'no value', 
+                'none'=>'none',
+                'small'=>'small', 
+                'regular'=>'regular',
+                'large'=>'large'
+            ]
+        ],
+        'size'=>[
+            'description'=>'set a size',
+            'group'=>'styling',
+            'values'=>[
+                ''=>'no value',
+                'lg'=>'',
+                'sm'=>'',
+                'xs'=>'',
+                'flat'=>'',
+            ]
+        ],
+        'variant'=>[
+            'description'=>'coloring style',
+            'group'=>'styling',
+            'values'=>[
+                ''=>'no value',
+                'outline'=>'small stripe on top',
+                'solid'=>'full filled widget',
+                'gradient'=>'full filled with gradient',
+            ]
+        ],
+        'visibility'=>[
+            'description'=>'',
+            'group'=>'customizing',
+            'values'=>[
+                ''=>'no value', 
+                '0'=>'hide', 
+                '1'=>'show',
+            ]
+        ],
+        // for keys: state
+        'windowstate'=>[
+            'description'=>'state of a resizable widget',
+            'group'=>'customizing',
+            'values'=>[
+                ''=>'no value', 
+                'collapsed'=>'header only', 
+                'maximized'=>'full window',
+            ]
+        ],
+        // for keys: dismissable
+        'yesno'=>[
+            'description'=>'',
+            'group'=>'customizing',
+            'values'=>[
+                ''=>'no value', 
+                '0'=>'no', 
+                '1'=>'yes',
+            ]
+        ],
+    ];
+
+    var $_aValueMappings=[
+        'shadow'=>[
+            'default'  => '',
+            'none'     => 'shadow-none',
+            'small'    => 'shadow-small',
+            'regular'  => 'shadow',
+            'large'    => 'shadow-lg',
+        ]
+    ];
+
+    var $_aElements=[];
+    
+    /**
+     * instance of htmlelements
+     * @var object
+     */
+    var $_oHtml=false;
+    
+    
+    // ----------------------------------------------------------------------
+    // 
+    // CONSTRUCTOR
+    // 
+    // ----------------------------------------------------------------------
+    public function __construct() {
+        $this->_oHtml=new htmlelements();
+        $this->_initElements();
+        return true;
+    }
+
+    // ----------------------------------------------------------------------
+    // 
+    // PRIVATE FUNCTIONS 
+    // 
+    // ----------------------------------------------------------------------
+    
+    /**
+     * verify if an item has a correct value
+     * it returns false if a key is not defined to be checked
+     * it returns true if it was validated successfully
+     * it dies with an errror, if a value check failed
+     * 
+     * @param string  $sType      type; key in $_aValidItems; one of bgcolor|color|type|size
+     * @param string  $sValue     value to check
+     * @param string  $sReferrer  optional: method that called this function
+     */
+    protected function _DELETE_ME___checkValue($sType, $sValue, $sReferrer=false){
+        if (!$sValue || !array_key_exists($sType, $this->_aValidItems)){
+            return false;
+        }
+        if(array_search($sValue, $this->_aValidItems[$sType])===false){
+            echo "ERROR: ".($sReferrer ? $sReferrer.' - ' : '')."value [$sValue] is not a valid for type [$sType]; it must be one of ".implode("|", $this->_aValidItems[$sType]).'<br>';
+        }
+        return true;
+    }
+
+    /**
+     * used in cosntructor
+     * initialize all element definitions
+     */
+    protected function _initElements(){
+        $this->_aElements=[
+
+            // ------------------------------------------------------------
+            'alert'=>[
+                'label'=>'Alert',
+                'description'=>'Colored box with title and a text',
+                'method'=>'getAlert',
+        
+                'params'=>[
+                    'type'        => ['select'=>$this->aPresets['type'],     'example_value'=>'warning'],
+                    'dismissible' => ['select'=>$this->aPresets['yesno'],    'example_value'=>''],
+                    'title'       => [
+                        'description'=>'Title in a bit bigger font', 
+                        'group'=>'content',
+                        'example_value'=>'Alert title'
+                    ],
+                    'text'        => [
+                        'description'=>'Message text', 
+                        'group'=>'content',
+                        'example_value'=>'I am a message. Read me, please.'
+                    ],
+                ]
+            ],
+            // ------------------------------------------------------------
+            'badge'=>[
+                'label'=>'Badge',
+                'description'=>'Tiny additional info; mostly as counter',
+                'method'=>'getBadge',
+        
+                'params'=>[
+                    'type'        => ['select'=>$this->aPresets['type'],     'example_value'=>'danger'],
+                    'bgcolor'     => ['select'=>$this->aPresets['bgcolor'],  'example_value'=>''],
+                    'class'       => [
+                        'group'=>'styling', 
+                        'description'=>'optional: css classes', 
+                        'example_value'=>''
+                    ],
+                    'id'          => [
+                        'group'=>'customizing', 
+                        'description'=>'optional: id attribute', 
+                        'example_value'=>''
+                    ],
+                    'title'       => [
+                        'group'=>'content', 
+                        'description'=>'optional: title attribute for mouseover', 
+                        'example_value'=>'Errors: 5'
+                    ],
+                    'text'        => [
+                        'group'=>'content', 
+                        'description'=>'Text or value in the badge', 
+                        'example_value'=>'5'
+                    ],
+                ]
+            ],
+            // ------------------------------------------------------------
+            'button'=>[
+                'label'=>'Button',
+                'description'=>'Buttons<br>In this component you can add other parmeter keys too - these will be added as attributes in the button tag.',
+                'method'=>'getButton',
+        
+                'params'=>[
+                    'type'        => ['select'=>$this->aPresets['type'],     'example_value'=>'primary'],
+                    'size'        => ['select'=>$this->aPresets['size'],     'example_value'=>''],
+                    'class'       => [
+                        'group'=>'styling', 
+                        'description'=>'optional: css classes', 
+                        'example_value'=>''
+                    ],
+                    'text'        => [
+                        'group'=>'content', 
+                        'description'=>'Text/ html code on the button', 
+                        'example_value'=>'Click me'
+                    ],
+                ]
+            ],
+            // ------------------------------------------------------------
+            'callout'=>[
+                'label'=>'Callout',
+                'description'=>'Kind of infobox',
+                'method'=>'getCallout',
+        
+                'params'=>[
+                    'type'        => ['select'=>$this->aPresets['type'],     'example_value'=>'danger'],
+                    'class'       => [
+                        'group'=>'styling', 
+                        'description'=>'optional: css classes', 
+                        'example_value'=>''
+                    ],
+                    'title'       => [
+                        'group'=>'content', 
+                        'description'=>'Title in a bit bigger font', 
+                        'example_value'=>'I am a callout'
+                    ],
+                    'text'        => [
+                        'group'=>'content',
+                        'description'=>'Message text', 
+                        'example_value'=>'Here is some description to whatever.'
+                    ],
+                ]
+            ],
+            // ------------------------------------------------------------
+            'card'=>[
+                'label'=>'Card',
+                'description'=>'Content box with header, text, footer',
+                'method'=>'getCard',
+        
+                'params'=>[
+                    'type'        => ['select'=>$this->aPresets['type'],     'example_value'=>'primary'],
+                    'variant'     => ['select'=>$this->aPresets['variant'],  'example_value'=>'outline'],
+                    'class'       => [
+                        'group'=>'styling', 
+                        'description'=>'optional: css classes', 
+                        'example_value'=>''
+                    ],
+                    'state'       => [
+                        'group'=>'customizing', 
+                        'select'=>$this->aPresets['windowstate'], 
+                        'example_value'=>''
+                    ],
+        
+                    'tb-collapse' => ['description'=>'show minus symbol as collapse button', 'select'=>$this->aPresets['visibility'], 'example_value'=>''],
+                    'tb-expand'   => ['description'=>'show plus symbol to expand card', 'select'=>$this->aPresets['visibility'], 'example_value'=>''],
+                    'tb-maximize' => ['description'=>'show maximize button for fullscreen', 'select'=>$this->aPresets['visibility'], 'example_value'=>''],
+                    'tb-minimize' => ['description'=>'show minimize button to minimize', 'select'=>$this->aPresets['visibility'], 'example_value'=>''],
+                    'tb-remove'   => ['description'=>'show cross symbol to remove card', 'select'=>$this->aPresets['visibility'], 'example_value'=>''],
+        
+                    'title'       => [
+                        'group'=>'content', 
+                        'description'=>'Title in the top row', 
+                        'example_value'=>'I am a card'
+                    ],
+                    'tools'       => [
+                        'group'=>'content', 
+                        'description'=>'Html code for the top right', 
+                        'example_value'=>''
+                    ],
+                    'text'        => [
+                        'group'=>'content', 
+                        'description'=>'Main content', 
+                        'example_value'=>'Here is some beautiful content.'
+                    ],
+                    'footer'      => [
+                        'group'=>'content', 
+                        'description'=>'optional: footer content', 
+                        'example_value'=>'Footer'
+                    ],
+                ]
+            ],
+            // ------------------------------------------------------------
+            'infobox'=>[
+                'label'=>'Info box',
+                'description'=>'Box with icon to highlight a single value; optional with a progress bar',
+                'method'=>'getInfobox',
+        
+                'params'=>[
+                    'type'=>['select'=>$this->aPresets['type'],     'example_value'=>''],
+                    'iconbg'=>['select'=>$this->aPresets['type'],   'example_value'=>'info'],
+                    'shadow'=>['select'=>$this->aPresets['shadow'], 'example_value'=>''],
+                    'icon'=>[
+                        'group'=>'content', 
+                        'description'=>'css class for an icon', 
+                        'example_value'=>'far fa-thumbs-up'
+                    ],
+                    'text'=>[
+                        'group'=>'content', 
+                        'description'=>'short information text', 
+                        'example_value'=>'Likes'
+                    ],
+                    'number'=>[
+                        'group'=>'content', 
+                        'description'=>'a number to highlight', 
+                        'example_value'=>"41,410"
+                    ],
+                    'progressvalue'=>[
+                        'group'=>'content', 
+                        'description'=>'optional: progress value 0..100 to draw a progress bar', 
+                        'example_value'=>70
+                    ],
+                    'progresstext'=>[
+                        'group'=>'content', 
+                        'description'=>'optional: text below progress bar', 
+                        'example_value'=>'70% Increase in 30 Days'
+                    ]
+                ]
+            ],
+            // ------------------------------------------------------------
+            'smallbox'=>[
+                'label'=>'Small box',
+                'description'=>'Solid colored box to highlight a single value; optional with a link',
+                'method'=>'getSmallbox',
+        
+                'params'=>[
+                    'type'=>['select'=>$this->aPresets['type'],     'example_value'=>'info'],
+                    'shadow'=>['select'=>$this->aPresets['shadow'], 'example_value'=>''],
+        
+                    'icon'=>['group'=>'content', 'description'=>'css class for an icon', 'example_value'=>'fas fa-shopping-cart'],
+        
+                    'text'=>['group'=>'content', 'description'=>'short information text', 'example_value'=>'New orders'],
+                    'number'=>['group'=>'content', 'description'=>'a number to highlight', 'example_value'=>"150"],
+                    'url'=>['group'=>'content', 'description'=>'optional: url to set a link on the bottom', 'example_value'=>'#'],
+                    'linktext'=>['group'=>'content', 'optional: description'=>'linktext', 'example_value'=>'More info']
+                ]
+            ],
+        ];
+    }
+    /**
+     * helper function: a shortcut for $this->_oHtml->getTag
+     * @param  string  $sTag         name of html tag
+     * @param  array   $aAttributes  array of its attributes
+     */
+    protected function _tag($sTag, $aAttributes, $sContent=false){
+        if ($sContent){
+            $aAttributes['label']=(isset($aAttributes['label']) ? $aAttributes['label'] : '') . $sContent;
+        }
+        return $this->_oHtml->getTag($sTag, $aAttributes);
+    }
+    // ----------------------------------------------------------------------
+    // 
+    // PUBLIC FUNCTIONS AdminLTE 3.2
+    // 
+    // ----------------------------------------------------------------------
+
+    /**
+     * render a page by using template 
+     * @param  string  $stemplate  html template with placeholders
+     * @param  array   $aReplace   key = what to replace .. value = new value
+     */
+    public function render($sTemplate, $aReplace){
+        return str_replace(
+            array_keys($aReplace),
+            array_values($aReplace),
+            $sTemplate
+        );
+    }
+    
+
+    /**
+     * add a wrapper: wrap some content into a tag
+     * 
+     * @param  string  $sContent  html content inside
+     * @return string
+     */
+    public function addWrapper($sTag, $aOptions, $sContent){
+        $aOptions['label']=$sContent;
+        return $this->_tag($sTag, $aOptions)."\n";
+    }
+
+    // ----------------------------------------------------------------------
+    // 
+    // PUBLIC FUNCTIONS :: NAVIGATION
+    // 
+    // ----------------------------------------------------------------------
+
+
+    /** 
+     * get a single navigation item on top bar
+     * 
+     * @param  array    $aLink   Array of html attributes; key children can contain subitems
+     * @param  integer  $iLevel  Menu level; 1=top bar; 2=pupup menu with subitems
+     * @return string
+     */
+    public function getNavItem($aLink, $iLevel=1){
+        static $iCounter;
+        if(!isset($iCounter)){
+            $iCounter=0;
+        }
+        
+        // special menu entry: horizontal bar (label is "-")
+        if($aLink['label']=='-'){
+            return '<div class="dropdown-divider"></div>';
+        }
+
+        $aChildren=isset($aLink['children']) && is_array($aLink['children']) && count($aLink['children']) ? $aLink['children'] : false;
+
+        $aLink['class']='nav-link'
+            . (isset($aLink['class']) ? ' '.$aLink['class'] : '')
+            . ($aChildren ? ' dropdown-toggle' : '')
+            ;
+        if($aChildren){
+            $iCounter++;
+            $sNavId="navbarDropdown".$iCounter;
+            $aLink=array_merge($aLink,[
+                'id'=>$sNavId,
+                'role'=>"button",
+                'data-toggle'=>"dropdown",
+                'aria-haspopup'=>"true",
+                'aria-expanded'=>"false",
+            ]);
+            unset($aLink['children']); // remove from html attributes to draw
+        }
+        $sReturn=$this->_tag('a', $aLink)."\n";
+        if($aChildren){ 
+            $iLevel++;
+            $sReturn.=$this->addWrapper(
+                    'div', 
+                    [ 
+                        'aria-labelledby'=> $sNavId,
+                        'class'=>'dropdown-menu'
+                    ], 
+                    $this->getNavItems($aChildren, $iLevel)
+                )."\n";
+            $iLevel--;
+        }
+   
+        if($iLevel==1){
+            $sLiClass='nav-item'.($aChildren ? ' dropdown' : '');
+            $sReturn=$this->addWrapper(
+                'li', 
+                ['class'=>$sLiClass],
+                $sReturn 
+            );
+        }
+        return $sReturn;
+    }
+    /** 
+     * get a navigation item for top bar
+     * 
+     */
+    public function getNavItems($aLinks, $iLevel=1){
+        $sReturn='';
+        if (!$aLinks || !is_array($aLinks) || !count($aLinks)){
+            return false;
+        }
+        foreach($aLinks as $aLink){
+            $sReturn.=$this->getNavItem($aLink, $iLevel);
+        }
+        return $sReturn;
+    }
+    /**
+     * get a top left navigation for a top navigation bar
+     * 
+     * @example
+     * <code>
+     * $aTopnav=[
+     *     ['href'=>'/index.php', 'label'=>'MyHome' , 'class'=>'bg-gray'],
+     *     ['href'=>'#',          'label'=>'Contact'],
+     *     ['href'=>'#',          'label'=>'Help',
+     *         'children'=>[
+     *             ['href'=>'#',      'label'=>'FAQ'],
+     *             ['label'=>'-'],
+     *             ['href'=>'#',      'label'=>'Support'],
+     *         ]
+     *     ]
+     * ];
+     *  echo '<nav class="main-header navbar navbar-expand navbar-white navbar-light">'
+     *     .$renderAdminLTE->getTopNavigation($aTopnav)
+     *     .'</nav>'
+     * </code>
+     * 
+     * @param  array  $aNavitems   array of navigation items/ tree
+     * @param  array  $aUlOptions  array of html attrubutes for wrapping UL tag
+     * @return string
+     */
+    public function getTopNavigation($aNavItems, $aUlOptions=['class'=>'navbar-nav']){
+        array_unshift($aNavItems, ['class'=>'nav-link', 'data-widget'=>'pushmenu', 'href'=>'#', 'role'=>'button', 'label'=>'<i class="fas fa-bars"></i>']);
+        return $this->addWrapper('ul', $aUlOptions, $this->getNavItems($aNavItems));
+    }
+
+    // ----------------------------------------------------------------------
+
+
+    /** 
+     * get a navigation items for sidebar
+     * @param  array  $aLinks  list of link items
+     */
+    public function getNavi2Items($aLinks){
+        $sReturn='';
+        if (!$aLinks || !is_array($aLinks) || !count($aLinks)){
+            return false;
+        }
+        foreach($aLinks as $aLink){
+            // to render active or open links: 
+            $aLink['class']='nav-link' . (isset($aLink['class']) ? ' '.$aLink['class'] : '');
+
+            $aChildren=isset($aLink['children']) ? $aLink['children'] : false;
+            $aLiClass='nav-item' . ($aChildren && strstr($aLink['class'], 'active') ? ' menu-open' : '');
+            $sSubmenu='';
+            if($aChildren){
+                unset($aLink['children']);                
+                $aLink['label'].='<i class="right fas fa-angle-left"></i>';
+                $sSubmenu.=$this->getSidebarNavigation($aChildren, ['class'=>'nav nav-treeview']);
+            }
+            $aLink['label']=$this->addWrapper('p', [], $aLink['label']);
+            $sReturn.=$this->addWrapper(
+                'li', ['class'=>$aLiClass],
+                $this->_tag('a', $aLink).$sSubmenu
+            )."\n";
+        }
+        return $sReturn;
+    }
+
+    /**
+     * 
+     */
+    public function getSidebarNavigation($aNavItems, $aUlOptions=[
+            'class'=>'nav nav-pills nav-sidebar flex-column nav-flat_ nav-child-indent',
+            'data-widget'=>'treeview',
+            'role'=>'menu',
+            'data-accordion'=>'false'
+            ])
+    {
+        return $this->addWrapper(
+                'ul', $aUlOptions, 
+                $this->getNavi2Items($aNavItems)
+            )."\n";
+    }
+
+    // ----------------------------------------------------------------------
+    // 
+    // PUBLIC FUNCTIONS :: CONTENT - BASIC FUNCTIONS
+    // 
+    // ----------------------------------------------------------------------
+    
+    /**
+     * add page row
+     * 
+     * @param  string  $sContent  html content inside
+     * @return string
+     */
+    public function addRow($sContent){
+        return $this->addWrapper('div', ['class'=>'row'], $sContent);
+    }
+
+    /**
+     * add page column
+     * 
+     * @param  string   $sContent  html content inside
+     * @param  integer  $iCols     column width; 12 = full width
+     * @param  string   $sFloat    css value for float attribute; default=false
+     * @return string
+     */
+    public function addCol($sContent, $iCols=6, $sFloat=false){
+        return $this->addWrapper('div', ['class'=>'col-md-'.$iCols, 'style'=>'float:'.$sFloat], $sContent);
+    }
+
+    // ----------------------------------------------------------------------
+    // 
+    // PUBLIC FUNCTIONS :: CONTENT - WIDGET HELPERS
+    // 
+    // ----------------------------------------------------------------------
+
+
+    /**
+     * get a list of all defined components that can be rendered
+     * @param  {bool}  $bSendData  flag: send including subkeys of the hash; default: false (keys only)
+     * @return {array}
+     */
+    public function getComponents($bSendData=false){
+        return $bSendData
+            ? $this->_aElements
+            : array_keys($this->_aElements)
+        ;
+    }
+    /**
+     * get data of a component
+     * @param  {string}  $sComponent  id of the component
+     * @return {array}
+     */
+    public function getComponent($sComponent){
+        if(!isset($this->_aElements[$sComponent])){
+            return false;
+        }
+        $aReturn=array_merge(['id'=>$sComponent], $this->_aElements[$sComponent]);
+        unset($aReturn['params']);
+        return $aReturn;
+    }
+
+    /**
+     * get parameter keys of a component
+     * @param  {string}  $sComponent  id of the component
+     * @param  {bool}    $bSendData  flag: send including subkeys of the hash; default: false (keys only)
+     * @return {array}
+     */
+    public function getComponentParamkeys($sComponent, $bSendData=false){
+        if(!isset($this->_aElements[$sComponent])){
+            return false;
+        }
+        $aKeys=array_keys($this->_aElements[$sComponent]['params']);
+        if(!$bSendData){
+            return $aKeys;
+        }
+        $aReturn=[];
+        foreach($aKeys as $sKey){
+            $aReturn[$sKey]=$this->getComponentParamkey($sComponent, $sKey);
+        }
+        // $aReturn=$this->_aElements[$sComponent]['params'];
+        return $aReturn;
+    }
+
+    /**
+     * get information a parameter keys of a component
+     * @param  {string}  $sComponent  id of the component
+     * @param  {string}  $sKey        key in the options array
+     * @return {array}
+     */
+    public function getComponentParamkey($sComponent, $sKey){
+        if(!isset($this->_aElements[$sComponent]['params'][$sKey])){
+            return false;
+        }
+        $aReturn=$this->_aElements[$sComponent]['params'][$sKey];
+        // get description from a preset
+        if(!isset($aReturn['description']) && isset($aReturn['select']['description'])){
+            $aReturn['description']=$aReturn['select']['description'];
+        }
+        if(!isset($aReturn['group']) && isset($aReturn['select']['group'])){
+            $aReturn['group']=$aReturn['select']['group'];
+        }
+        return $aReturn;
+    }
+
+    /**
+     * get a flat list of valid parameters for a key in a component
+     * @param  {string}  $sComponent  id of the component
+     * @param  {string}  $sKey        key in the options array
+     * @return {array}
+     */
+    public function getValidParamValues($sComponent, $sKey){
+        $aOptionkey=$this->getComponentParamkey($sComponent, $sKey);
+        if(!$aOptionkey || !isset($aOptionkey['select']['values'])){
+            return false;
+        }
+        return array_keys($aOptionkey['select']['values']);
+    }
+
+
+    // ----------------------------------------------------------------------
+
+    /**
+     * helper: add a css value with prefix
+     * this handles option keys in get[COMPONENT] methods
+     * if a value is set then this function returns a space + prefix (param 2) + value
+     * @param  {string}  $sValue   option value
+     * @param  {string}  $sPrefix  prefix in front of css value
+     * @return {string}
+     */
+    protected function _addClassValue($sValue, $sPrefix=''){
+        return $sValue ? ' '.$sPrefix.$sValue : '';
+    }
+
+    /**
+     * helper function for get[COMPONENTNAME] methods:
+     * ensure that all wanted keys exist in an array. Non existing keys will be added with value false
+     * @return array
+     */
+    protected function _ensureOptions($sComponent, $aOptions=[]){
+
+        $aParams=$this->getComponentParamkeys($sComponent, 0);
+        if(!$aParams){
+            $aOptions['_infos'][]="Warning: no definition was found for component $sComponent.";
+            return $aOptions;
+        }
+        foreach ($aParams as $sKey){
+            if(!isset($aOptions) || !isset($aOptions[$sKey])){
+                $aOptions[$sKey]=false;
+                if(!isset($aOptions['_infos'])){
+                    $aOptions['_infos']=[];
+                }
+                $aOptions['_infos'][]="added missing key: $sKey";
+            }
+
+            // $aParamdata
+            $aValidvalues=$this->getValidParamValues($sComponent, $sKey);
+            if($aValidvalues){
+                if(array_search($aOptions[$sKey], $aValidvalues)===false){
+                    echo "ERROR: [".$sComponent."] value &quot;".$aOptions[$sKey]."&quot; is not a valid for param key [".$sKey."]; it must be one of ".implode("|", $aValidvalues).'<br>';
+                }
+            }
+    
+            // $this->_checkValue($sKey, $aOptions[$sKey], __METHOD__);
+        }
+        // echo '<pre>' . print_r($aOptions, 1) . '</pre>';
+        return $aOptions;
+    }
+    // ----------------------------------------------------------------------
+    // 
+    // PUBLIC FUNCTIONS :: CONTENT - WIDGETS
+    // 
+    // ----------------------------------------------------------------------
+
+    /**
+     * return a alert box      
+     * https://adminlte.io/themes/v3/pages/UI/general.html
+     * 
+     * @param type $aOptions  hash with keys for all options
+     *                          - type - one of [none]|danger|info|primary|success|warning
+     *                          - dismissible - if dismissible - one of true|false; default: false
+     *                          - title
+     *                          - text
+     * @return string
+     */
+    public function getAlert($aOptions){
+        $aOptions=$this->_ensureOptions('alert', $aOptions);
+        $aAlertIcons=[
+            'danger'=>'icon fas fa-ban',
+            'info'=>'icon fas fa-info',
+            'warning'=>'icon fas fa-exclamation-triangle',
+            'success'=>'icon fas fa-check',
+        ];
+
+        $aElement=[
+            'class'=>'alert'
+                . $this->_addClassValue($aOptions['type'], 'alert-')
+                . $this->_addClassValue($aOptions['dismissible'], 'alert-')
+                ,
+            'label'=>''
+                . ($aOptions['dismissible'] ? '<button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>' : '')
+                . $this->_tag('h5', [
+                    'label'=> ''
+                        .(isset($aAlertIcons[$aOptions['type']]) ? '<i class="'.$aAlertIcons[$aOptions['type']].'"></i> ' : '')
+                        .$aOptions['title']
+                    ])
+                .$aOptions['text']
+        ];
+
+        return $this->_tag('div', $aElement);
+    }
+
+    /**
+     * get html code for a badge
+     * 
+     * Examples
+     * <span class="badge badge-danger navbar-badge">3</span>
+     * <span title="3 New Messages" class="badge badge-warning">3</span>
+     * <span class="right badge badge-danger">New</span>
+     * <span class="badge badge-danger float-right">$350</span>
+     * 
+     * @param array $aOptions  hash with keys for all options
+     *                          - bgcolor - background color (without prefix "bg")
+     *                          - class   - css class
+     *                          - id      - optional: id attribute
+     *                          - text    - visible text
+     *                          - title   - optional: title attribute
+     *                          - type    - one of [none]|danger|dark|info|primary|secondary|success|warning
+     */
+    public function getBadge($aOptions){
+        $aOptions=$this->_ensureOptions('badge', $aOptions);
+        $aElement=[];
+        $aElement['class']='badge'
+            . $this->_addClassValue($aOptions['class'],   '')
+            . $this->_addClassValue($aOptions['type'],    'badge-')
+            . $this->_addClassValue($aOptions['bgcolor'], 'bg-')
+            ;
+        if ($aOptions['id']){
+            $aElement['id']=$aOptions['id'];
+        }
+        $aElement['title']=$aOptions['title'];
+        $aElement['label']=$aOptions['text'];
+
+        return $this->_tag('span', $aElement);
+    }
+
+    /**
+     * Get a button.
+     * You can use any other key that are not named here. Those keys will be rendered 
+     * as additional html attributes without modification.
+     * https://adminlte.io/themes/v3/pages/UI/buttons.html
+     * 
+     * <button type="button" class="btn btn-block btn-default">Default</button>
+     * @param type $aOptions  hash with keys for all options
+     *                          - type  - one of [none]|danger|dark|info|primary|secondary|success|warning
+     *                          - size  - one of [none]|lg|sm|xs|flat
+     *                          - class - any css class for customizing, eg. "disabled"
+     *                          - icon  - not supported yet
+     *                          - text  - text on button
+     * @return string
+     */
+    public function getButton($aOptions){
+        $aOptions=$this->_ensureOptions('button', $aOptions);
+        $aElement=$aOptions;
+        $aElement['class']='btn'
+            . $this->_addClassValue($aOptions['type'],    'btn-')
+            . $this->_addClassValue($aOptions['size'],    'btn-')
+            . $this->_addClassValue($aOptions['class'],   '')
+            ;
+        $aElement['label']=$aOptions['text'] ? $aOptions['text'] : '&nbsp;';
+        foreach(['_infos', 'type', 'size', 'icon', 'text'] as $sDeleteKey){
+            unset($aElement[$sDeleteKey]);
+        }
+        return $this->_tag('button', $aElement);
+    }
+
+    /**
+     * get a callout (box with coloered left border; has type, title + text)
+     * https://adminlte.io/themes/v3/pages/UI/general.html
+     * 
+     * @param type $aOptions  hash with keys for all options
+     *                        >> styling
+     *                          - type    - one of [none]|danger|dark|info|primary|secondary|success|warning
+     *                          - class   - optional css class
+     * 
+     *                        >> texts/ html content
+     *                          - title   - text: title of the card
+     *                          - text    - text: content of the card
+     * @return string
+     */
+    public function getCallout($aOptions){
+        $aOptions=$this->_ensureOptions('callout', $aOptions);
+        $sClass='callout'
+            . $this->_addClassValue($aOptions['type'],    'callout-')
+            . $this->_addClassValue($aOptions['class'],   '')
+            ;
+
+        return $this->addWrapper(
+            'div', ['class'=>$sClass],
+            ($aOptions['title'] ? $this->_tag('h5', ['label'=>$aOptions['title']]) : '')
+            .($aOptions['text'] ? $this->_tag('p', ['label'=>$aOptions['text']]) : '')
+        );
+    }
+
+    /**
+     * get a card
+     * https://adminlte.io/docs/3.2/components/cards.html
+     * https://adminlte.io/docs/3.2/javascript/card-widget.html
+     * 
+     * @param type $aOptions  hash with keys for all options
+     *                        >> styling
+     *                          - variant: "default"  - titlebar is colored
+     *                                     "outline"  - a small stripe on top border is colored
+     *                                     "solid"    - whole card is colored
+     *                                     "gradient" - whole card is colored with a gradient
+     *                          - type    - one of [none]|danger|dark|info|primary|secondary|success|warning
+     *                          - class   - any css class for customizing, eg. "disabled"
+     *                          - state   - one of [none]|collapsed|maximized
+     * 
+     *                        >> toolbar icons - set to true to show it; default: none of it is visible
+     *                         - tb-collapse
+     *                         - tb-expand    it is added automatically if you set 'state'=>'collapsed'
+     *                         - tb-maximize 
+     *                         - tb-minimize  it is added automatically if you set 'state'=>'maximized'
+     *                         - tb-remove
+     * 
+     *                        >> texts/ html content
+     *                          - title   - text: title of the card
+     *                          - tools   - text: titlebar top right elements
+     *                          - text    - text: content of the card
+     *                          - footer  - text: footer of the card
+     * @return string
+     */
+    public function getCard($aOptions){
+        $aOptions=$this->_ensureOptions('card', $aOptions);
+        // css class prefixes based on "variant" value
+        $aVariants=[
+            'default'  => 'card-',
+            'outline'  => 'card-outline card-',
+            'solid'    => 'bg-',
+            'gradient' => 'bg-gradient-',
+        ];
+
+        // window states: css class and toolbar buttons to add
+        $aStates=[
+            'collapsed'=>[ 'class'=>'collapsed-card', 'tool'=>'tb-expand'],
+            'maximized'=>[ 'class'=>'maximized-card', 'tool'=>'tb-minimize'],
+        ];
+        $aTools=[
+            'tb-collapse'=>'<button type="button" class="btn btn-tool" data-card-widget="collapse"><i class="fas fa-minus"></i></button>',
+            'tb-expand'=>'<button type="button" class="btn btn-tool" data-card-widget="collapse"><i class="fas fa-plus"></i></button>',
+
+            'tb-maximize'=>'<button type="button" class="btn btn-tool" data-card-widget="maximize"><i class="fas fa-expand"></i></button>',
+            'tb-minimize'=>'<button type="button" class="btn btn-tool" data-card-widget="maximize"><i class="fas fa-compress"></i></button>',
+
+            'tb-remove'=>'<button type="button" class="btn btn-tool" data-card-widget="remove"><i class="fas fa-times"></i></button>',
+        ];
+
+        // print_r($aOptions);
+
+        $sVariantPrefix=$aVariants[$aOptions['variant']] ? $aVariants[$aOptions['variant']] : $aVariants['default'];
+        $sClass='card'
+                . $this->_addClassValue($aOptions['type'],    $sVariantPrefix)
+                . $this->_addClassValue($aOptions['class'],   '')
+                ;
+
+        // check window state
+        foreach($aStates as $sStatus=>$aStatus){
+            if($aOptions['state']===$sStatus){
+                $sClass.=' '.$aStatus['class'];
+                $aOptions[$aStatus['tool']]=1;
+            }
+        }
+
+        // add toolbar buttons - from given options or by window state
+        foreach($aTools as $sTool=>$sHtml){
+            $aOptions['tools'].=($aOptions[$sTool] ? $sHtml : '');
+        }
+        // build parts of the card
+        $sCardHeader=$this->addWrapper('div', ['class'=>'card-header'],
+            $this->_tag('h3', ['class'=>'card-title', 'label'=>$aOptions['title']])
+            . ($aOptions['tools'] ? $this->_tag('div', ['class'=>'card-tools', 'label'=>$aOptions['tools']]) : '')
+        );
+
+        $sCardBody=$this->_tag('div', ['class'=>'card-body', 'label'=>$aOptions['text']]);
+        $sCardFooter=$aOptions['footer'] ? $this->_tag('div', ['class'=>'card-footer', 'label'=>$aOptions['footer']]) : '';
+
+        // merge all
+        return $this->addWrapper('div', ['class'=>$sClass], $sCardHeader.$sCardBody.$sCardFooter);
+    }
+
+
+    /**
+     * return an info-box:
+     * A colored box with large icon, text and a value.
+     * https://adminlte.io/docs/3.2/components/boxes.html
+     * 
+     * @param type $aOptions  hash with keys for all options
+     *                        styling:
+     *                          - type    - color of the box; one of [none]|danger|dark|info|primary|secondary|success|warning
+     *                          - iconbg  - background color or type of icon; use it for default type (type="")
+     *                          - shadow  - size of shadow; one of [none] (=default: between small and regular)|none|small|regular|large 
+     * 
+     *                        content
+     *                          - icon    - icon class
+     *                          - text    - information text
+     *                          - number  - value (comes in bold text)
+     *                          - progressvalue - integer: progress bar; range: 0..100
+     *                          - progresstext  - text below progress bar
+     * @return string
+     */
+    public function getInfobox($aOptions){
+        $aOptions=$this->_ensureOptions('infobox', $aOptions);
+
+        // print_r($aOptions);
+        $sClass='info-box'
+                . $this->_addClassValue($aOptions['type'],    'bg-')
+                . $this->_addClassValue($aOptions['class'],   '')
+                .($aOptions['shadow'] && isset($this->_aValueMappings['shadow'][$aOptions['shadow']]) 
+                    ? ' '.$this->_aValueMappings['shadow'][$aOptions['shadow']] : '')
+                ;
+        
+        // build parts
+        $sIcon=$aOptions['icon'] 
+            ? $this->addWrapper("span", [
+                    'class'=>'info-box-icon'.($aOptions['iconbg'] ? ' bg-'.$aOptions['iconbg'] : '')
+                ], $this->_tag('i',['class'=>$aOptions['icon']])) 
+            : ''
+            ;
+        $sContent=$this->addWrapper("div", ['class'=>'info-box-content'],
+            ''
+            . ($aOptions['text']   ? $this->_tag('span', ['class'=>'info-box-text',   'label'=>$aOptions['text']])   : '')
+            . ($aOptions['number'] ? $this->_tag('span', ['class'=>'info-box-number', 'label'=>$aOptions['number']]) : '')
+            . ($aOptions['progressvalue']!==false && $aOptions['progressvalue']!=='' 
+                ? $this->addWrapper('div', ['class'=>'progress'],
+                        $this->_tag('div', ['class'=>'progress-bar'. ($aOptions['iconbg'] ? ' bg-'.$aOptions['iconbg'] : ''), 'style'=>'width: '.(int)$aOptions['progressvalue'].'%' ]) 
+                    )
+                    . ($aOptions['progresstext'] ? $this->_tag('span', ['class'=>'progress-description', 'label'=>$aOptions['progresstext']]) : '' )
+                : ''    
+                ) 
+        );
+
+        // merge all
+        return $this->_tag('div', ['class'=>$sClass], $sIcon.$sContent);
+    }
+
+
+    /**
+     * return an info-box:
+     * A colored box with large icon, text and a value.
+     * https://adminlte.io/docs/3.2/components/boxes.html
+     * https://adminlte.io/themes/v3/pages/widgets.html
+     * 
+     * @param type $aOptions  hash with keys for all options
+     *                        styling:
+     *                          - type    - color of the box; one of [none]|danger|dark|info|primary|secondary|success|warning
+
+     *                        content
+     *                          - icon    - icon class for icon on the right
+     *                          - text    - information text
+     *                          - number  - value (comes in bold text)
+     *                          - url     - integer: progress bar; range: 0..100
+     *                          - linktext- text below progress bar
+     * @return string
+     */
+    public function getSmallbox($aOptions){
+        $aOptions=$this->_ensureOptions('smallbox', $aOptions);
+        $aShadows=[
+            'default'  => '',
+            'none'     => 'shadow-none',
+            'small'    => 'shadow-small',
+            'regular'  => 'shadow',
+            'large'    => 'shadow-lg',
+        ];
+        // print_r($aOptions);
+        $sClass='small-box'
+                . $this->_addClassValue($aOptions['type'],    'bg-')
+                .($aOptions['shadow'] && isset($this->_aValueMappings['shadow'][$aOptions['shadow']]) 
+                    ? ' '.$this->_aValueMappings['shadow'][$aOptions['shadow']] : '')
+                ;
+        
+        // build parts
+        $sContent=$this->addWrapper("div", ['class'=>'inner'],
+            ''
+            . ($aOptions['number'] ? $this->_tag('h3', ['label'=>$aOptions['number']]) : '')
+            . ($aOptions['text']   ? $this->_tag('p', ['class'=>'info-box-text',   'label'=>$aOptions['text']])   : '')
+        );
+        $sIcon=$aOptions['icon'] 
+            ? $this->addWrapper("div", ['class'=>'icon'], 
+                $this->_tag('i',['class'=>$aOptions['icon']])) 
+            : ''
+            ;
+        $sFooter=($aOptions['url']
+            ? $this->addWrapper("a", [
+                'class'=>'small-box-footer',
+                'href'=>$aOptions['url'],
+                ],
+                ''
+                . ($aOptions['linktext'] ? $aOptions['linktext'] : $aOptions['url'])
+                . ' '
+                . $this->_tag('i',['class'=>'fas fa-arrow-circle-right'])
+            )
+            : ''
+        );
+
+        // merge all
+        return $this->_tag('div', ['class'=>$sClass], $sContent.$sIcon.$sFooter);
+    }
+
+
+/*
+
+<div class="info-box">
+  <span class="info-box-icon bg-info"><i class="far fa-bookmark"></i></span>
+  <div class="info-box-content">
+    <span class="info-box-text">Bookmarks</span>
+    <span class="info-box-number">41,410</span>
+    <div class="progress">
+      <div class="progress-bar bg-info" style="width: 70%"></div>
+    </div>
+    <span class="progress-description">
+      70% Increase in 30 Days
+    </span>
+  </div>
+</div>
+
+
+
+  <div class="info-box bg-success">
+    <span class="info-box-icon"><i class="far fa-thumbs-up"></i></span>
+    <div class="info-box-content">
+      <span class="info-box-text">Likes</span>
+      <span class="info-box-number">41,410</span>
+      <div class="progress">
+        <div class="progress-bar" style="width: 70%"></div>
+      </div>
+      <span class="progress-description">
+        70% Increase in 30 Days
+      </span>
+    </div>
+  </div>
+*/
+  
+
+
+
+
+
+
+
+
+}
diff --git a/config/page.tpl.php b/config/page.tpl.php
new file mode 100644
index 0000000000000000000000000000000000000000..3659b4545b783f4ff1f1201e17d01e6230c1ca9b
--- /dev/null
+++ b/config/page.tpl.php
@@ -0,0 +1,455 @@
+<!DOCTYPE html>
+
+<html lang="en">
+
+<head>
+    <meta charset="utf-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1">
+    <title>{{PAGE_TITLE}}</title>
+
+    <script type="text/javascript" src="js/asimax.class.js"></script>
+    
+    <script type="text/javascript" src="vendor/jquery/3.6.1/jquery.min.js"></script>
+
+    <!-- visjs -->
+    <script type="text/javascript" src="vendor/vis/4.21.0/vis.min.js"></script>
+    <link href="vendor/vis/4.21.0/vis-timeline-graph2d.min.css" rel="stylesheet" type="text/css"/>
+    
+    <!-- datatable -->
+    <script type="text/javascript" src="vendor/datatables/1.10.15/js/jquery.dataTables.min.js"></script>
+    <link href="vendor/datatables/1.10.15/css/jquery.dataTables.min.css" rel="stylesheet" type="text/css"/>
+    
+    <!-- fontawesome -->
+    <link href="vendor/font-awesome/5.15.4/css/all.min.css" rel="stylesheet" type="text/css"/>
+
+
+    <!--
+    <link rel="stylesheet" href="{{DIR_ADMINLTEPLUGINS}}/fontawesome-free/css/all.min.css">
+    -->
+    <!-- Adminlte -->
+    <link rel="stylesheet" href="{{DIR_ADMINLTE}}/css/adminlte.min.css?v=3.2.0">
+
+    <link rel="stylesheet" href="/main.css">
+    
+    <!--
+    <script nonce="b14481d0-1a31-4cec-b6e8-b5ad6020a5a9">
+        (function(w, d) {
+            ! function(cM, cN, cO, cP) {
+                cM.zarazData = cM.zarazData || {};
+                cM.zarazData.executed = [];
+                cM.zaraz = {
+                    deferred: [],
+                    listeners: []
+                };
+                cM.zaraz.q = [];
+                cM.zaraz._f = function(cQ) {
+                    return function() {
+                        var cR = Array.prototype.slice.call(arguments);
+                        cM.zaraz.q.push({
+                            m: cQ,
+                            a: cR
+                        })
+                    }
+                };
+                for (const cS of ["track", "set", "debug"]) cM.zaraz[cS] = cM.zaraz._f(cS);
+                cM.zaraz.init = () => {
+                    var cT = cN.getElementsByTagName(cP)[0],
+                        cU = cN.createElement(cP),
+                        cV = cN.getElementsByTagName("title")[0];
+                    cV && (cM.zarazData.t = cN.getElementsByTagName("title")[0].text);
+                    cM.zarazData.x = Math.random();
+                    cM.zarazData.w = cM.screen.width;
+                    cM.zarazData.h = cM.screen.height;
+                    cM.zarazData.j = cM.innerHeight;
+                    cM.zarazData.e = cM.innerWidth;
+                    cM.zarazData.l = cM.location.href;
+                    cM.zarazData.r = cN.referrer;
+                    cM.zarazData.k = cM.screen.colorDepth;
+                    cM.zarazData.n = cN.characterSet;
+                    cM.zarazData.o = (new Date).getTimezoneOffset();
+                    if (cM.dataLayer)
+                        for (const cZ of Object.entries(Object.entries(dataLayer).reduce(((c_, da) => ({
+                                ...c_[1],
+                                ...da[1]
+                            }))))) zaraz.set(cZ[0], cZ[1], {
+                            scope: "page"
+                        });
+                    cM.zarazData.q = [];
+                    for (; cM.zaraz.q.length;) {
+                        const db = cM.zaraz.q.shift();
+                        cM.zarazData.q.push(db)
+                    }
+                    cU.defer = !0;
+                    for (const dc of [localStorage, sessionStorage]) Object.keys(dc || {}).filter((de => de.startsWith("_zaraz_"))).forEach((dd => {
+                        try {
+                            cM.zarazData["z_" + dd.slice(7)] = JSON.parse(dc.getItem(dd))
+                        } catch {
+                            cM.zarazData["z_" + dd.slice(7)] = dc.getItem(dd)
+                        }
+                    }));
+                    cU.referrerPolicy = "origin";
+                    cU.src = "/cdn-cgi/zaraz/s.js?z=" + btoa(encodeURIComponent(JSON.stringify(cM.zarazData)));
+                    cT.parentNode.insertBefore(cU, cT)
+                };
+                ["complete", "interactive"].includes(cN.readyState) ? zaraz.init() : cM.addEventListener("DOMContentLoaded", zaraz.init)
+            }(w, d, 0, "script");
+        })(window, document);
+    </script>
+    -->
+</head>
+
+<body class="hold-transition {{PAGE_SKIN}} {{PAGE_LAYOUT}}">
+    <div class="wrapper">
+
+        {{NAVI_TOP}}
+        <!--
+        <nav class="main-header navbar navbar-expand navbar-white navbar-light">
+
+            <ul class="navbar-nav">
+                <li class="nav-item">
+                    <a class="nav-link" data-widget="pushmenu" href="#" role="button"><i class="fas fa-bars"></i></a>
+                </li>
+                <li class="nav-item d-none d-sm-inline-block">
+                    <a href="index3.html" class="nav-link">Home</a>
+                </li>
+                <li class="nav-item d-none d-sm-inline-block">
+                    <a href="#" class="nav-link">Contact</a>
+                </li>
+            </ul>
+
+            <ul class="navbar-nav ml-auto">
+
+                <li class="nav-item">
+                    <a class="nav-link" data-widget="navbar-search" href="#" role="button">
+                        <i class="fas fa-search"></i>
+                    </a>
+                    <div class="navbar-search-block">
+                        <form class="form-inline">
+                            <div class="input-group input-group-sm">
+                                <input class="form-control form-control-navbar" type="search" placeholder="Search"
+                                    aria-label="Search">
+                                <div class="input-group-append">
+                                    <button class="btn btn-navbar" type="submit">
+                                        <i class="fas fa-search"></i>
+                                    </button>
+                                    <button class="btn btn-navbar" type="button" data-widget="navbar-search">
+                                        <i class="fas fa-times"></i>
+                                    </button>
+                                </div>
+                            </div>
+                        </form>
+                    </div>
+                </li>
+
+                <li class="nav-item dropdown">
+                    <a class="nav-link" data-toggle="dropdown" href="#">
+                        <i class="far fa-comments"></i>
+                        <span class="badge badge-danger navbar-badge">3</span>
+                    </a>
+                    <div class="dropdown-menu dropdown-menu-lg dropdown-menu-right">
+                        <a href="#" class="dropdown-item">
+
+                            <div class="media">
+                                <img src="dist/img/user1-128x128.jpg" alt="User Avatar"
+                                    class="img-size-50 mr-3 img-circle">
+                                <div class="media-body">
+                                    <h3 class="dropdown-item-title">
+                                        Brad Diesel
+                                        <span class="float-right text-sm text-danger"><i class="fas fa-star"></i></span>
+                                    </h3>
+                                    <p class="text-sm">Call me whenever you can...</p>
+                                    <p class="text-sm text-muted"><i class="far fa-clock mr-1"></i> 4 Hours Ago</p>
+                                </div>
+                            </div>
+
+                        </a>
+                        <div class="dropdown-divider"></div>
+                        <a href="#" class="dropdown-item">
+
+                            <div class="media">
+                                <img src="dist/img/user8-128x128.jpg" alt="User Avatar"
+                                    class="img-size-50 img-circle mr-3">
+                                <div class="media-body">
+                                    <h3 class="dropdown-item-title">
+                                        John Pierce
+                                        <span class="float-right text-sm text-muted"><i class="fas fa-star"></i></span>
+                                    </h3>
+                                    <p class="text-sm">I got your message bro</p>
+                                    <p class="text-sm text-muted"><i class="far fa-clock mr-1"></i> 4 Hours Ago</p>
+                                </div>
+                            </div>
+
+                        </a>
+                        <div class="dropdown-divider"></div>
+                        <a href="#" class="dropdown-item">
+
+                            <div class="media">
+                                <img src="dist/img/user3-128x128.jpg" alt="User Avatar"
+                                    class="img-size-50 img-circle mr-3">
+                                <div class="media-body">
+                                    <h3 class="dropdown-item-title">
+                                        Nora Silvester
+                                        <span class="float-right text-sm text-warning"><i
+                                                class="fas fa-star"></i></span>
+                                    </h3>
+                                    <p class="text-sm">The subject goes here</p>
+                                    <p class="text-sm text-muted"><i class="far fa-clock mr-1"></i> 4 Hours Ago</p>
+                                </div>
+                            </div>
+
+                        </a>
+                        <div class="dropdown-divider"></div>
+                        <a href="#" class="dropdown-item dropdown-footer">See All Messages</a>
+                    </div>
+                </li>
+
+                <li class="nav-item dropdown">
+                    <a class="nav-link" data-toggle="dropdown" href="#">
+                        <i class="far fa-bell"></i>
+                        <span class="badge badge-warning navbar-badge">15</span>
+                    </a>
+                    <div class="dropdown-menu dropdown-menu-lg dropdown-menu-right">
+                        <span class="dropdown-header">15 Notifications</span>
+                        <div class="dropdown-divider"></div>
+                        <a href="#" class="dropdown-item">
+                            <i class="fas fa-envelope mr-2"></i> 4 new messages
+                            <span class="float-right text-muted text-sm">3 mins</span>
+                        </a>
+                        <div class="dropdown-divider"></div>
+                        <a href="#" class="dropdown-item">
+                            <i class="fas fa-users mr-2"></i> 8 friend requests
+                            <span class="float-right text-muted text-sm">12 hours</span>
+                        </a>
+                        <div class="dropdown-divider"></div>
+                        <a href="#" class="dropdown-item">
+                            <i class="fas fa-file mr-2"></i> 3 new reports
+                            <span class="float-right text-muted text-sm">2 days</span>
+                        </a>
+                        <div class="dropdown-divider"></div>
+                        <a href="#" class="dropdown-item dropdown-footer">See All Notifications</a>
+                    </div>
+                </li>
+                <li class="nav-item">
+                    <a class="nav-link" data-widget="fullscreen" href="#" role="button">
+                        <i class="fas fa-expand-arrows-alt"></i>
+                    </a>
+                </li>
+                <li class="nav-item">
+                    <a class="nav-link" data-widget="control-sidebar" data-slide="true" href="#" role="button">
+                        <i class="fas fa-th-large"></i>
+                    </a>
+                </li>
+            </ul>
+        </nav>
+        -->
+
+        <aside class="main-sidebar sidebar-dark-primary elevation-4">
+
+            {{BRAND}}
+            <!--
+            <a href="index3.html" class="brand-link">
+                <img src="dist/img/AdminLTELogo.png" alt="AdminLTE Logo" class="brand-image img-circle elevation-3"
+                    style="opacity: .8">
+                <span class="brand-text font-weight-light">AdminLTE 3</span>
+            </a>
+            -->
+
+            <div class="sidebar">
+
+                <!--
+                <div class="user-panel mt-3 pb-3 mb-3 d-flex">
+                    <div class="image">
+                        <img src="dist/img/user2-160x160.jpg" class="img-circle elevation-2" alt="User Image">
+                    </div>
+                    <div class="info">
+                        <a href="#" class="d-block">Alexander Pierce</a>
+                    </div>
+                </div>
+
+                <div class="form-inline">
+                    <div class="input-group" data-widget="sidebar-search">
+                        <input class="form-control form-control-sidebar" type="search" placeholder="Search"
+                            aria-label="Search">
+                        <div class="input-group-append">
+                            <button class="btn btn-sidebar">
+                                <i class="fas fa-search fa-fw"></i>
+                            </button>
+                        </div>
+                    </div>
+                </div>
+                -->
+                {{NAVI_LEFT}}
+                <br><br>
+
+                <!--
+                <nav class="mt-2">
+                    <ul class="nav nav-pills nav-sidebar flex-column" data-widget="treeview" role="menu" data-accordion="false">
+
+                        <li class="nav-item menu-open">
+                            <a href="#" class="nav-link active">
+                                <i class="nav-icon fas fa-tachometer-alt"></i>
+                                <p>
+                                    Starter Pages
+                                    <i class="right fas fa-angle-left"></i>
+                                </p>
+                            </a>
+                            <ul class="nav nav-treeview">
+                                <li class="nav-item">
+                                    <a href="#" class="nav-link active">
+                                        <i class="far fa-circle nav-icon"></i>
+                                        <p>Active Page</p>
+                                    </a>
+                                </li>
+                                <li class="nav-item">
+                                    <a href="#" class="nav-link">
+                                        <i class="far fa-circle nav-icon"></i>
+                                        <p>Inactive Page</p>
+                                    </a>
+                                </li>
+                            </ul>
+                        </li>
+                        <li class="nav-item">
+                            <a href="#" class="nav-link">
+                                <i class="nav-icon fas fa-th"></i>
+                                <p>
+                                    Simple Link
+                                    <span class="right badge badge-danger">New</span>
+                                </p>
+                            </a>
+                        </li>
+                    </ul>
+                </nav>
+                -->
+
+            </div>
+
+        </aside>
+
+        <div class="content-wrapper px-4 py-2">
+
+
+            <div class="content-header">
+                <div class="container-fluid">
+                    <div class="row mb-2">
+                        <div class="col-sm-6">
+                            {{PAGE_HEADER_LEFT}}
+
+                            <!-- <h1 class="m-0">Starter Page</h1> -->
+                        </div>
+                        <div class="col-sm-6">
+                            <ol class="breadcrumb float-sm-right">
+                                {{PAGE_HEADER_RIGHT}}
+                                
+                                <!--
+                                <li class="breadcrumb-item"><a href="#">Home</a></li>
+                                <li class="breadcrumb-item active">Starter Page</li>
+                                -->
+                            </ol>
+                        </div>
+                    </div>
+                </div>
+            </div>
+
+
+
+            <div class="content">
+
+
+                <div class="container-fluid">
+
+                    {{PAGE_BODY}}
+
+                    <!--
+                    <div class="row">
+                        <div class="col-lg-6">
+                            <div class="card">
+                                <div class="card-body">
+                                    <h5 class="card-title">Card title</h5>
+                                    <p class="card-text">
+                                        Some quick example text to build on the card title and make up the bulk of the
+                                        card's
+                                        content.
+                                    </p>
+                                    <a href="#" class="card-link">Card link</a>
+                                    <a href="#" class="card-link">Another link</a>
+                                </div>
+                            </div>
+                            <div class="card card-primary card-outline">
+                                <div class="card-body">
+                                    <h5 class="card-title">Card title</h5>
+                                    <p class="card-text">
+                                        Some quick example text to build on the card title and make up the bulk of the
+                                        card's
+                                        content.
+                                    </p>
+                                    <a href="#" class="card-link">Card link</a>
+                                    <a href="#" class="card-link">Another link</a>
+                                </div>
+                            </div>
+                        </div>
+
+                        <div class="col-lg-6">
+                            <div class="card">
+                                <div class="card-header">
+                                    <h5 class="m-0">Featured</h5>
+                                </div>
+                                <div class="card-body">
+                                    <h6 class="card-title">Special title treatment</h6>
+                                    <p class="card-text">With supporting text below as a natural lead-in to additional
+                                        content.</p>
+                                    <a href="#" class="btn btn-primary">Go somewhere</a>
+                                </div>
+                            </div>
+                            <div class="card card-primary card-outline">
+                                <div class="card-header">
+                                    <h5 class="m-0">Featured</h5>
+                                </div>
+                                <div class="card-body">
+                                    <h6 class="card-title">Special title treatment</h6>
+                                    <p class="card-text">With supporting text below as a natural lead-in to additional
+                                        content.</p>
+                                    <a href="#" class="btn btn-primary">Go somewhere</a>
+                                </div>
+                            </div>
+                        </div>
+
+                    </div>
+                    -->
+                </div>
+            </div>
+
+        </div>
+
+
+        <aside class="control-sidebar control-sidebar-dark">
+
+            <div class="p-3">
+                <h5>Title</h5>
+                <p>Sidebar content</p>
+            </div>
+        </aside>
+
+
+        <footer class="main-footer">
+
+            <div class="float-right d-none d-sm-inline">
+                {{PAGE_FOOTER_RIGHT}}
+                <!--
+                Anything you want
+                -->
+            </div>
+
+            {{PAGE_FOOTER_LEFT}}
+            <!--
+            <strong>Copyright &copy; 2014-2021 <a href="https://adminlte.io">AdminLTE.io</a>.</strong> All rights
+            reserved.
+            -->
+        </footer>
+    </div>
+
+    <script src="{{DIR_ADMINLTEPLUGINS}}/bootstrap/js/bootstrap.bundle.min.js"></script>
+    <script src="{{DIR_ADMINLTE}}/js/adminlte.min.js?v=3.2.0"></script>
+    <script type="text/javascript" src="js/functions.js"></script>
+</body>
+
+</html>
\ No newline at end of file
diff --git a/config/page_replacements.php b/config/page_replacements.php
new file mode 100644
index 0000000000000000000000000000000000000000..b2cb42a0384f8f569a930e0067a27ff6561250b7
--- /dev/null
+++ b/config/page_replacements.php
@@ -0,0 +1,76 @@
+<?php
+
+return [
+    '{{DIR_ADMINLTE}}' =>'/vendor/admin-lte/3.2.0',
+    '{{DIR_ADMINLTEPLUGINS}}' =>'/vendor/admin-lte-plugins',
+    '{{PAGE_SKIN}}'    =>'',
+    '{{PAGE_TITLE}}'   =>'Cronlog Viewer',
+    '{{PAGE_LAYOUT}}'  =>'layout-navbar-fixed layout-fixed sidebar-mini',
+    '{{NAVI_TOP}}'     =>'<nav class="main-header navbar navbar-expand navbar-white navbar-light"><ul class="navbar-nav" id="instances"></ul></nav>',
+    '{{BRAND}}'        =>'<a href="/index.php" class="brand-link bg-red">
+                            Cronlog viewer
+                            <span class="brand-text font-weight-light">v2.0</span>
+                            </a>',
+    '{{NAVI_LEFT}}'    =>'
+                            <br>
+                            <div class="form-inline">
+                                <div class="input-group">
+                                    <input id="serverfiltertext" class="form-control form-control-sidebar" type="search" placeholder="Search"
+
+                                        onchange="filterServers();"
+                                        onkeypress="filterServers();"
+                                        onkeyup="filterServers();"
+                
+                                        >
+                                    <div class="input-group-append">
+                                        <button class="btn btn-sidebar"
+                                        onclick="$(\'#serverfiltertext\').val(\'\'); filterServers();"                                        >
+                                        ×
+                                        </button>
+                                    </div>
+                                </div>
+                            </div>
+                            <div class="user-panel mt-3 pb-3 mb-3 d-flex">
+
+                            <div id="selectserver" class="active"></div>
+                          </div>',
+    '{{PAGE_HEADER_LEFT}}'=>'<h2 id="lblServername">Server w&auml;hlen...</h2>
+                            <nav id="subnav" class="navbar navbar-expand navbar-light tabs">
+                            <ul class="navbar-nav">
+                                <li class="nav-item">
+                                    <a href="#cronlogs"    onclick="setTab(this); return false;"  class="nav-link active">
+                                        <i class="far fa-file-alt"></i> Logs</a></li>
+                                <li class="nav-item">
+                                    <a href="#cronhistory" onclick="setTab(this); return false;" class="nav-link">
+                                        <i class="fas fa-history"></i> History</a></li>
+                                <li class="nav-item">
+                                    <a href="#graph"       onclick="setTab(this); return false;" class="nav-link">
+                                        <i class="far fa-chart-bar"></i> Timeline</a></li>
+                            </ul>
+                            </nav>',
+    '{{PAGE_HEADER_RIGHT}}'=>'<span id="counter" style="float: right;"></span>',
+    '{{PAGE_BODY}}'=>'<div id="tabcontent">
+
+                        <div id="cronlogs">
+                          <div class="card card-primary card-outline active">
+                            <div class="card-body" id="cronlogs-content"><br>Moment ...</div></div>
+                        </div>
+                        <div id="cronhistory"> 
+                          <div class="card card-info card-outline">
+                            <div class="card-body" id="cronhistory-content"><br>Moment ...</div></div>
+                        </div>
+                        <div id="graph">
+                        <div class="card card-success card-outline">
+                            <div class="card-body" id="graph-content"><br>Moment ...</div></div>
+                        </div>
+                      </div>
+
+
+                      <div id="overlay" ondblclick="closeOverlay();">
+                          <div id="showlog" class="active"><br>Moment ...</div>
+                      </div>
+          
+                      ',
+    '{{PAGE_FOOTER_LEFT}}'=>'2018 -2022 // University of Bern * Institute for Medical education',
+    '{{PAGE_FOOTER_RIGHT}}'=>'Source: <a href="https://git-repo.iml.unibe.ch/iml-open-source/cronlog-viewer/">git-repo.iml.unibe.ch</a>',
+];
\ No newline at end of file
diff --git a/index.html b/index.html
deleted file mode 100644
index 40e3f99b835b102ea6625e9e28e34d2c4c33d37f..0000000000000000000000000000000000000000
--- a/index.html
+++ /dev/null
@@ -1,62 +0,0 @@
-<!doctype html>
-<html lang="de">
-    <head>
-        <meta charset="utf-8" />
-        <meta http-equiv="Pragma" content="no-cache">
-        <meta name="robots" content="noindex,nofollow">
-
-        <title>Cronjob-Viewer</title>
-        
-        <script type="text/javascript" src="vendor/jquery/3.6.1/jquery.min.js"></script>
-        <script type="text/javascript" src="js/asimax.class.js"></script>
-        <script type="text/javascript" src="js/functions.js"></script>
-        
-        <script type="text/javascript" src="vendor/vis/4.21.0/vis.min.js"></script>
-        <link href="vendor/vis/4.21.0/vis-timeline-graph2d.min.css" rel="stylesheet" type="text/css"/>
-        
-        <script type="text/javascript" src="vendor/datatables/1.10.15/js/jquery.dataTables.min.js"></script>
-        <link href="vendor/datatables/1.10.15/css/jquery.dataTables.min.css" rel="stylesheet" type="text/css"/>
-        
-        <link href="vendor/font-awesome/5.15.4/css/all.min.css" rel="stylesheet" type="text/css"/>
-        <link rel="stylesheet" type="text/css" href="main.css">
-    </head>
-    <body>
-        <div id="errorlog"></div>
-        <header>
-            <div id="instances">...</div>
-            <h1><a href="?"><span class="imllogo"></span> CronjobViewer</a></h1>
-        </header>
-        <nav class="servers">
-            <div id="selectserver" class="active">...</div>
-        </nav>
-        <div id="content">
-
-            <h2 id="lblServername">Server w&auml;hlen...</h2>
-            <span id="counter" style="float: right;"></span>
-            <nav class="tabs">
-                <a href="#cronlogs"    onclick="setTab(this); return false;" class="active"><i class="far fa-file-alt"></i> Logs</a>
-                <a href="#cronhistory" onclick="setTab(this); return false;"><i class="fas fa-history"></i> History</a>
-                <a href="#graph"       onclick="setTab(this); return false;"><i class="far fa-chart-bar"></i> Timeline</a>
-                
-            </nav><br><br>  
-
-            <!--
-            <button onclick="refreshPage(); return false;"><i class="fas fa-sync"></i> Reload</button>
-            -->
-
-            <div id="tabcontent">
-                <div id="cronlogs" class="active"><br>Moment ...</div>
-                <div id="cronhistory"><br>Moment ...</div>
-                <div id="graph"><br>Moment ...</div>
-            </div>
-
-        </div>
-        <div style="clear: both"></div><br><br><br><br>
-        <footer>
-            &copy; 2018 -2022<br>
-            Source: <a href="https://git-repo.iml.unibe.ch/iml-open-source/cronlog-viewer/" target="_blank">git-repo.iml.unibe.ch</a>    
-        </footer>
-        <div id="overlay" ondblclick="closeOverlay();">
-            <div id="showlog" class="active"><br>Moment ...</div>
-        </div>
-</body></html>
\ No newline at end of file
diff --git a/index.php b/index.php
new file mode 100644
index 0000000000000000000000000000000000000000..64a0288bd10fe97cc05a032e5207c18301e67028
--- /dev/null
+++ b/index.php
@@ -0,0 +1,10 @@
+<?php
+
+require_once('classes/render-adminlte.class.php');
+$renderAdminLTE=new renderadminlte();
+
+$aReplace=include("./config/page_replacements.php");
+$sTemplate=file_get_contents('config/page.tpl.php');
+
+// ---------- send content
+echo $renderAdminLTE->render($sTemplate,$aReplace);
diff --git a/main.css b/main.css
index 47b0e1746ff92be5e9a82650d36354542db2c6db..eb39b828548ec376ea4c4b306c66d5f7d4a4a497 100644
--- a/main.css
+++ b/main.css
@@ -1,76 +1,31 @@
-/* 
-    Author     : hahn
-*/
-:root{
-  --bg-main:#fff;
-  --bg-header:#eee;  
-  --border: #cde;
-}
 
 
-a {color: #38a;text-decoration: none;}
-a:hover {text-decoration: underline;}
-body{background:var(--bg-main); color:#456; font-family: verdana,arial; font-size:1.0em; margin: 0;}
-button{background:#46a; border: none; color:#fff; padding: 0.2em 1em; border-radius: 0.3em; border: 2px solid rgba(0,0,0,0.1); box-shadow: 0.2em 0.2em 0.5em #aaa;}
-button.add{background:#8c8;}
-button.del{background:#c88;}
-button:hover{background:#68c;}
-button:active{box-shadow: none; }
-
-footer{position: fixed; bottom: 1em; right: 1em; background: var(--bg-header); border-top: 1px solid var(--border); padding: 1em; text-align: right;}
-
-header{border-bottom: 1px solid var(--border); background:var(--bg-header); margin: 0 0 0.3em; padding: 1.5em 1em;}
-h1{margin: 0 0 0.3em; padding: 0; margin: 0;}
-h1 a{color: #38a;}
-h1 a:hover{text-decoration: none;}
-  #instances{float: right;}
-  #instances a{border: 0px solid; padding: 0.4em;}
-  #instances a:hover{background: var(--bg-main);}
-  #instances a.active{background: var(--bg-main);border-top: 1px solid var(--border); border-left: 1px solid var(--border);}
-
-h2{color:#379;}
-h2 i{color:#abc; font-size: 140%;}
-h3{color: #39b;}
-h3:before{content: ':: '}
-i.fa{font-size: 150%; }
-i.fa.lookup{font-size: 100%; opacity: 0.4;}
-
-nav.servers{float: left; margin-right: 1em;}
-#selectserver{min-height: 30em; border-right: 0px dashed #cde; padding: 0 0.5em; background: #fff; }
-
-nav.tabs a{display: block; float: left; background: rgba(0,60,60,0.05); padding: 0.5em 1em; color:#345; text-decoration: none; margin-right: 2px; border-top: 4px solid rgba(0,0,0,0.01);}
-nav.tabs a.active{background: #d0e0e0; border-color: rgb(255,0,51); }
-nav.tabs a:hover{border-color: #abc;}
-
-input{border: 1px solid #ddd; padding: 0.3em;}
-option{font-family: verdana,arial; font-size:1.2em; }
-option:hover{background: #eee;}
-#selectserver select {border: 0; width: 100%;}
+/* ----- serverlist on the left side */
+#selectserver{min-height: 20em;max-height: 30em; }
+#selectserver select{background: none; border: none; max-height: 100%; color: #ddd;}
 
-p.hint{margin-bottom: 1em; background:#fed; padding: 1em; }
-table{border: 1px solid #ccc;}
-tr:hover{background:#eee;}
-th{background:#eee; padding:0.5em;}
-td{padding:0.3em;}
+/* ----- head area */
+
+#counter{border-bottom: 1px solid #ccc;}
+#counter div{background:#bcd; background:#aaa;  height: 5px; transition: width 0.3s ;}
 
-.imllogo:before {background: rgb(255,0,51);color: #fff;padding: 0.5em 0.3em;content: 'IML'; font-family: "arial"; text-shadow: none;}
+
+#subnav .nav-link.active{
+    background: #e0e8f0;
+    border-top: 0px solid; 
+}
 
 /* ----- tabbed content */
 #cronhistory,#cronlogs,#graph,#overlay{display: none;}
 #tabcontent div.active{display: block;}
 
-#overlay{position: fixed; width: 100%; height: 100%; background: rgba(0,0,0,0.4); top:0; left: 0;}
-#showlog{background:#fff; border: 3px solid #888; padding: 1em; margin: 2%; height: 90%; overflow: scroll;}
 
-.log-rem{color:#aaa; font-style: italic;}
-.log-var{color:#088;}
-.log-value{color:#008;}
-pre div:hover{background:rgba(0,0,0,0.1);}
-
-#counter{color:#abc;border-bottom: 1px solid #eee; margin-right: 1em;}
-#counter div{background:#bcd; height: 5px; transition: width 1s ;}
 #errorlog {background:#fcc; color:#800;}
-/* ----- override datatable defaukts */
+
+p.hint{margin-bottom: 1em; background:#fed; padding: 1em; }
+
+
+/* ----- override datatable defaults */
 .dataTables_wrapper{clear: none;float: left; margin: auto 1px;}
 table.dataTable tbody tr.even{background: #f0f4f8;}
 /* table.dataTable tbody tr.odd{} */
@@ -86,8 +41,7 @@ table.dataTable tbody tr:hover{background:rgba(0,0,0,0.1);}
 table.dataTable tbody td ul{margin: 0; padding-left: 0.8em;}
 
 
-/* timeline
-*/
+/* ----- timeline */
 .vis-item.timeline-result-error{background:#fcc; border-color: #800}
 .vis-item.timeline-result-ok{background:#cfc;border-color: #080}
 
@@ -106,31 +60,12 @@ table.dataTable tbody td ul{margin: 0; padding-left: 0.8em;}
     border-bottom: 4px solid #abc;
   }
 
-    /* 
-  .vis-h0, .vis-h1,.vis-h2,.vis-h3, .vis-h4, .vis-h5, .vis-h6,.vis-h7,.vis-h18,.vis-h19,.vis-h20,.vis-h21,.vis-h22,.vis-h23{
-    background: #e0e4e8;
-  }
-  .vis-h8, .vis-h9,.vis-h10,.vis-h11, .vis-h12, .vis-h13, .vis-h14,.vis-h15,.vis-h16,.vis-h17{
-    background: #f0f4f8;
-  }
-  alternating column backgrounds
-  .vis-time-axis .vis-odd {
-    background: #fff;
-  }
-  .vis-time-axis .vis-even {
-    background: #f0f4f8;
-  }
-  .vis-time-axis{
-    background: #fea;
-  }
+/* ----- overlay */
 
-gray background in weekends, white text color 
-  .vis-time-axis .vis-grid.vis-saturday,
-  .vis-time-axis .vis-grid.vis-sunday {
-    background: #ed8 !important;
-  }
-  .vis-time-axis .vis-text.vis-saturday,
-  .vis-time-axis .vis-text.vis-sunday {
-  }
+#overlay{position: fixed; width: 100%; height: 100%; background: rgba(0,0,0,0.4); top:0; left: 0; z-index: 10000;}
+#showlog{background:#fff; border: 3px solid #888; padding: 1em; margin: 2%; height: 90%; overflow: scroll;}
 
-*/
+.log-rem{color:#aaa; font-style: italic;}
+.log-var{color:#088;}
+.log-value{color:#008;}
+pre div:hover{background:rgba(0,0,0,0.1);}