Prechádzať zdrojové kódy

CSS is now all namespaced. (#48)

* CSS is now all namespaced.

Added classes throughout and changed all CSS selectors to be namespaced under the body's classname, and then additionally use all class names where appropriate.  This should mean less interference with embedding the script in other pages/sites, and hopefully resolve #47.
Andrew Collington 5 rokov pred
rodič
commit
2607296609
3 zmenil súbory, kde vykonal 134 pridanie a 139 odobranie
  1. 4 0
      README.md
  2. 101 108
      index.php
  3. 29 31
      src/status.jsx

+ 4 - 0
README.md

@@ -108,7 +108,11 @@ The composer.json file is provided to allow you to deploy the opcache gui a litt
 
 
 ## Releases
 ## Releases
 
 
+**Version 2.5.2**\
+CSS class names have been added and style rules updated to use them.
+
 **Version 2.5.1**\
 **Version 2.5.1**\
+A couple bug fixes and improvement on the optimisation level details.
 * optimisation_level now shows the levels of optimisations that will be performed rather than an abstract number
 * optimisation_level now shows the levels of optimisations that will be performed rather than an abstract number
 * Fixed issue #43
 * Fixed issue #43
 * Fixed issue #44
 * Fixed issue #44

+ 101 - 108
index.php

@@ -311,68 +311,66 @@ $opcache = OpCacheService::init($options);
     <script src="//cdn.jsdelivr.net/react/15.4.2/react-dom.min.js"></script>
     <script src="//cdn.jsdelivr.net/react/15.4.2/react-dom.min.js"></script>
     <script src="//cdn.jsdelivr.net/jquery/3.1.1/jquery.min.js"></script>
     <script src="//cdn.jsdelivr.net/jquery/3.1.1/jquery.min.js"></script>
     <style type="text/css">
     <style type="text/css">
-        body { font-family:sans-serif; font-size:90%; padding: 0; margin: 0 }
-        nav { padding-top: 20px; }
-        nav > ul { list-style-type: none; padding-left: 8px; margin: 0; border-bottom: 1px solid #ccc; }
-        nav > ul > li { display: inline-block; padding: 0; margin: 0 0 -1px 0; }
-        nav > ul > li > a { display: block; margin: 0 10px; padding: 15px 30px; border: 1px solid transparent; border-bottom-color: #ccc; text-decoration: none; }
-        nav > ul > li > a:hover { background-color: #f4f4f4; text-decoration: underline; }
-        nav > ul > li > a.active:hover { background-color: initial; }
-        nav > ul > li > a[data-for].active { border: 1px solid #ccc; border-bottom-color: #ffffff; border-top: 3px solid #6ca6ef; }
-        table { margin: 0 0 1em 0; border-collapse: collapse; border-color: #fff; width: 100%; table-layout: fixed; }
-        table caption { text-align: left; font-size: 1.5em; }
-        table tr { background-color: #99D0DF; border-color: #fff; }
-        table th { text-align: left; padding: 6px; background-color: #6ca6ef; color: #fff; border-color: #fff; font-weight: normal; }
-        table td { padding: 4px 6px; line-height: 1.4em; vertical-align: top; border-color: #fff; overflow: hidden; overflow-wrap: break-word; text-overflow: ellipsis;}
-        table tr:nth-child(odd) { background-color: #EFFEFF; }
-        table tr:nth-child(even) { background-color: #E0ECEF; }
-        #filelist table tr { background-color: #EFFEFF; }
-        #filelist table tr.alternate { background-color: #E0ECEF; }
-        td.pathname { width: 70%; }
-        footer { border-top: 1px solid #ccc; padding: 1em 2em; }
-        footer a { padding: 2em; text-decoration: none; opacity: 0.7; }
-        footer a:hover { opacity: 1; }
-        canvas { display: block; max-width: 100%; height: auto; margin: 0 auto; }
-        #tabs { padding: 2em; }
-        #tabs > div { display: none; }
-        #tabs > div#overview { display:block; }
-        #resetCache, #toggleRealtime, footer > a { background-position: 5px 50%; background-repeat: no-repeat; background-color: transparent; }
-        footer > a { background-position: 0 50%; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAAQCAYAAAAbBi9cAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyBpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEzNDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNSBXaW5kb3dzIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjE2MENCRkExNzVBQjExRTQ5NDBGRTUzMzQyMDVDNzFFIiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOjE2MENCRkEyNzVBQjExRTQ5NDBGRTUzMzQyMDVDNzFFIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6MTYwQ0JGOUY3NUFCMTFFNDk0MEZFNTMzNDIwNUM3MUUiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6MTYwQ0JGQTA3NUFCMTFFNDk0MEZFNTMzNDIwNUM3MUUiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz7HtUU1AAABN0lEQVR42qyUvWoCQRSF77hCLLKC+FOlCKTyIbYQUuhbWPkSFnZ2NpabUvANLGyz5CkkYGMlFtFAUmiSM8lZOVkWsgm58K079+fMnTusZl92BXbgDrTtZ2szd8fas/XBOzmBKaiCEFyTkL4pc9L8vgpNJJDyWtDna61EoXpO+xcFfXUVqtrf7Vx7m9Pub/EatvgHoYXD4ylztC14BBVwydvydgDPHPgNaErN3jLKIxAUmEvAXK21I18SJpXBGAxyBAaMlblOWOs1bMXFkMGeBFsi0pJNe/QNuV7563+gs8LfhrRfE6GaHLuRqfnUiKi6lJ034B44EXL0baTTJWujNGkG3kBX5uRyZuRkPl3WzDTBtzjnxxiDDq83yNxUk7GYuXM53jeLuMNavvAXkv4zrJkTaeGHAAMAIal3icPMsyQAAAAASUVORK5CYII='); font-size: 80%; }
-        #resetCache { background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAYAAABWzo5XAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoV2luZG93cykiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6NjBFMUMyMjI3NDlGMTFFNEE3QzNGNjQ0OEFDQzQ1MkMiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6NjBFMUMyMjM3NDlGMTFFNEE3QzNGNjQ0OEFDQzQ1MkMiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo2MEUxQzIyMDc0OUYxMUU0QTdDM0Y2NDQ4QUNDNDUyQyIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo2MEUxQzIyMTc0OUYxMUU0QTdDM0Y2NDQ4QUNDNDUyQyIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PplZ+ZkAAAD1SURBVHjazFPtDYJADIUJZAMZ4UbACWQENjBO4Ao6AW5AnODcADZQJwAnwJ55NbWhB/6zycsdpX39uDZNpsURtjgzwkDoCBecs5ITPGGMwCNAkIrQw+8ri36GhBHsavFdpILEo4wEpZxRigy009EhG760gr0VhFoyZfvJKPwsheIWIeGejBZRIxRVhMRFevbuUXBew/iE/lhlBduV0j8Jx+TvJEWPphq8n5li9utgaw6cW/h6NSt/JcnVBhQxotIgKTBrbNvIHo2G0x1rwlKqTDusxiAz6hHNL1zayTVqVKRKpa/LPljPH1sJh6l/oNSrZfwSYABtq3tFdZA5BAAAAABJRU5ErkJggg=='); }
-        #toggleRealtime { position: relative; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAAUCAYAAACAl21KAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoV2luZG93cykiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6ODE5RUU4NUE3NDlGMTFFNDkyMzA4QzY1RjRBQkIzQjUiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6ODE5RUU4NUI3NDlGMTFFNDkyMzA4QzY1RjRBQkIzQjUiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo4MTlFRTg1ODc0OUYxMUU0OTIzMDhDNjVGNEFCQjNCNSIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo4MTlFRTg1OTc0OUYxMUU0OTIzMDhDNjVGNEFCQjNCNSIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PpXjpvMAAAD2SURBVHjarFQBEcMgDKR3E1AJldA5wMEqAQmTgINqmILdFCChdUAdMAeMcukuSwnQbbnLlZLwJPkQIcrSiT/IGNQHNb8CGQDyRw+2QWUBqC+luzo4OKQZIAVrB+ssyKp3Bkijf0+ijzIh4wQppoBauMSjyDZfMSCDxYZMsfHF120T36AqWZMkgyguQ3GOfottJ5TKnHC+wfeRsC2oDVayPgr3bbN2tHBH3tWuJCPa0JUgKtFzMQrcZH3FNHAc0yOp1cCASALyngoN6lhDopkJWxdifwY9A3u7l29ImpxOFSWIOVsGwHKENIWxss2eBVKdOeeXAAMAk/Z9h4QhXmUAAAAASUVORK5CYII='); }
-        #counts { width: 270px; float: right; }
-        #counts > div > div { background-color: #ededed; margin-bottom: 10px; }
-        #counts > div > div > h3 { background-color: #cdcdcd; padding: 4px 6px; margin: 0; text-align: center; }
-        #counts > div > div > p { margin: 0; text-align: center; }
-        #counts > div > div > p span.large + span { font-size: 20pt; margin: 0; color: #6ca6ef; }
-        #counts > div > div > p span.large { color: #6ca6ef; font-size: 80pt; margin: 0; padding: 0; text-align: center; }
-        #info { margin-right: 280px; }
-        #frmFilter { width: 520px; }
-        #fileCacheOnly { margin-top: 0; }
-        .moreinfo > div { padding: 10px; }
-        .moreinfo > div > p { margin: 0; line-height: 1.75em; }
-        .metainfo { font-size: 80%; }
-        .hide { display: none; }
-        #toggleRealtime.pulse::before {
+        .opcache-gui { font-family:sans-serif; font-size:90%; padding: 0; margin: 0 }
+        .opcache-gui .hide { display: none; }
+        .opcache-gui .main-nav { padding-top: 20px; }
+        .opcache-gui .nav-tab-list { list-style-type: none; padding-left: 8px; margin: 0; border-bottom: 1px solid #ccc; }
+        .opcache-gui .nav-tab { display: inline-block; padding: 0; margin: 0 0 -1px 0; }
+        .opcache-gui .nav-tab-link { display: block; margin: 0 10px; padding: 15px 30px; border: 1px solid transparent; border-bottom-color: #ccc; text-decoration: none; }
+        .opcache-gui .nav-tab-link:hover { background-color: #f4f4f4; text-decoration: underline; }
+        .opcache-gui .nav-tab-link.active:hover { background-color: initial; }
+        .opcache-gui .nav-tab-link[data-for].active { border: 1px solid #ccc; border-bottom-color: #ffffff; border-top: 3px solid #6ca6ef; }
+        .opcache-gui .nav-tab-link-reset { background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAYAAABWzo5XAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoV2luZG93cykiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6NjBFMUMyMjI3NDlGMTFFNEE3QzNGNjQ0OEFDQzQ1MkMiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6NjBFMUMyMjM3NDlGMTFFNEE3QzNGNjQ0OEFDQzQ1MkMiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo2MEUxQzIyMDc0OUYxMUU0QTdDM0Y2NDQ4QUNDNDUyQyIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo2MEUxQzIyMTc0OUYxMUU0QTdDM0Y2NDQ4QUNDNDUyQyIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PplZ+ZkAAAD1SURBVHjazFPtDYJADIUJZAMZ4UbACWQENjBO4Ao6AW5AnODcADZQJwAnwJ55NbWhB/6zycsdpX39uDZNpsURtjgzwkDoCBecs5ITPGGMwCNAkIrQw+8ri36GhBHsavFdpILEo4wEpZxRigy009EhG760gr0VhFoyZfvJKPwsheIWIeGejBZRIxRVhMRFevbuUXBew/iE/lhlBduV0j8Jx+TvJEWPphq8n5li9utgaw6cW/h6NSt/JcnVBhQxotIgKTBrbNvIHo2G0x1rwlKqTDusxiAz6hHNL1zayTVqVKRKpa/LPljPH1sJh6l/oNSrZfwSYABtq3tFdZA5BAAAAABJRU5ErkJggg=='); }
+        .opcache-gui .nav-tab-link-realtime { position: relative; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAAUCAYAAACAl21KAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoV2luZG93cykiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6ODE5RUU4NUE3NDlGMTFFNDkyMzA4QzY1RjRBQkIzQjUiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6ODE5RUU4NUI3NDlGMTFFNDkyMzA4QzY1RjRBQkIzQjUiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo4MTlFRTg1ODc0OUYxMUU0OTIzMDhDNjVGNEFCQjNCNSIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo4MTlFRTg1OTc0OUYxMUU0OTIzMDhDNjVGNEFCQjNCNSIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PpXjpvMAAAD2SURBVHjarFQBEcMgDKR3E1AJldA5wMEqAQmTgINqmILdFCChdUAdMAeMcukuSwnQbbnLlZLwJPkQIcrSiT/IGNQHNb8CGQDyRw+2QWUBqC+luzo4OKQZIAVrB+ssyKp3Bkijf0+ijzIh4wQppoBauMSjyDZfMSCDxYZMsfHF120T36AqWZMkgyguQ3GOfottJ5TKnHC+wfeRsC2oDVayPgr3bbN2tHBH3tWuJCPa0JUgKtFzMQrcZH3FNHAc0yOp1cCASALyngoN6lhDopkJWxdifwY9A3u7l29ImpxOFSWIOVsGwHKENIWxss2eBVKdOeeXAAMAk/Z9h4QhXmUAAAAASUVORK5CYII='); }
+        .opcache-gui .nav-tab-link-realtime.pulse::before {
             content: ""; position: absolute;
             content: ""; position: absolute;
             top: 13px; left: 3px; width: 18px; height: 18px;
             top: 13px; left: 3px; width: 18px; height: 18px;
             z-index: 10; opacity: 0; background-color: transparent;
             z-index: 10; opacity: 0; background-color: transparent;
             border: 2px solid rgb(255, 116, 0); border-radius: 100%;
             border: 2px solid rgb(255, 116, 0); border-radius: 100%;
-            -webkit-animation: pulse 1s linear 2;
-            -moz-animation: pulse 1s linear 2;
             animation: pulse 1s linear 2;
             animation: pulse 1s linear 2;
         }
         }
+        .opcache-gui .tab-content-container { padding: 2em; }
+        .opcache-gui .tab-content { display: none; }
+        .opcache-gui .tab-content-overview { display:block; }
+        .opcache-gui .tab-content-overview-counts { width: 270px; float: right; }
+        .opcache-gui .tab-content-overview-info { margin-right: 280px; }
+        .opcache-gui .graph-widget { display: block; max-width: 100%; height: auto; margin: 0 auto; }
+        .opcache-gui .widget-panel { background-color: #ededed; margin-bottom: 10px; }
+        .opcache-gui .widget-header { background-color: #cdcdcd; padding: 4px 6px; margin: 0; text-align: center; }
+        .opcache-gui .widget-value { margin: 0; text-align: center; }
+        .opcache-gui .widget-value span.large + span { font-size: 20pt; margin: 0; color: #6ca6ef; }
+        .opcache-gui .widget-value span.large { color: #6ca6ef; font-size: 80pt; margin: 0; padding: 0; text-align: center; }
+        .opcache-gui .widget-info { margin: 0; padding: 10px; }
+        .opcache-gui .widget-info * { margin: 0; line-height: 1.75em; text-align: left; }
+        .opcache-gui .tables { margin: 0 0 1em 0; border-collapse: collapse; border-color: #fff; width: 100%; table-layout: fixed; }
+        .opcache-gui .tables tr { background-color: #99D0DF; border-color: #fff; }
+        .opcache-gui .tables th { text-align: left; padding: 6px; background-color: #6ca6ef; color: #fff; border-color: #fff; font-weight: normal; }
+        .opcache-gui .tables td { padding: 4px 6px; line-height: 1.4em; vertical-align: top; border-color: #fff; overflow: hidden; overflow-wrap: break-word; text-overflow: ellipsis;}
+        .opcache-gui .tables tr:nth-child(odd) { background-color: #EFFEFF; }
+        .opcache-gui .tables tr:nth-child(even) { background-color: #E0ECEF; }
+        .opcache-gui .tables.file-list-table tr { background-color: #EFFEFF; }
+        .opcache-gui .tables.file-list-table tr.alternate { background-color: #E0ECEF; }
+        .opcache-gui .file-filter { width: 520px; }
+        .opcache-gui .file-metainfo { font-size: 80%; }
+        .opcache-gui .file-pathname { width: 70%; display: block; }
+        .opcache-gui .nav-tab-link-reset,
+        .opcache-gui .nav-tab-link-realtime,
+        .opcache-gui .github-link { background-position: 5px 50%; background-repeat: no-repeat; background-color: transparent; }
+        .opcache-gui .main-footer { border-top: 1px solid #ccc; padding: 1em 2em; }
+        .opcache-gui .github-link { background-position: 0 50%; padding: 2em; text-decoration: none; opacity: 0.7; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAAQCAYAAAAbBi9cAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyBpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEzNDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNSBXaW5kb3dzIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjE2MENCRkExNzVBQjExRTQ5NDBGRTUzMzQyMDVDNzFFIiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOjE2MENCRkEyNzVBQjExRTQ5NDBGRTUzMzQyMDVDNzFFIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6MTYwQ0JGOUY3NUFCMTFFNDk0MEZFNTMzNDIwNUM3MUUiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6MTYwQ0JGQTA3NUFCMTFFNDk0MEZFNTMzNDIwNUM3MUUiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz7HtUU1AAABN0lEQVR42qyUvWoCQRSF77hCLLKC+FOlCKTyIbYQUuhbWPkSFnZ2NpabUvANLGyz5CkkYGMlFtFAUmiSM8lZOVkWsgm58K079+fMnTusZl92BXbgDrTtZ2szd8fas/XBOzmBKaiCEFyTkL4pc9L8vgpNJJDyWtDna61EoXpO+xcFfXUVqtrf7Vx7m9Pub/EatvgHoYXD4ylztC14BBVwydvydgDPHPgNaErN3jLKIxAUmEvAXK21I18SJpXBGAxyBAaMlblOWOs1bMXFkMGeBFsi0pJNe/QNuV7563+gs8LfhrRfE6GaHLuRqfnUiKi6lJ034B44EXL0baTTJWujNGkG3kBX5uRyZuRkPl3WzDTBtzjnxxiDDq83yNxUk7GYuXM53jeLuMNavvAXkv4zrJkTaeGHAAMAIal3icPMsyQAAAAASUVORK5CYII='); font-size: 80%; }
+        .opcache-gui .github-link:hover { opacity: 1; }
+        .opcache-gui .file-cache-only { margin-top: 0; }
         @media screen and (max-width: 750px) {
         @media screen and (max-width: 750px) {
-            #info { margin-right:auto; clear:both; }
-            nav > ul { border-bottom: 0; }
-            nav > ul > li { display: block; margin: 0; }
-            nav > ul > li > a { display: block; margin: 0 10px; padding: 10px 0 10px 30px; border: 0; }
-            nav > ul > li > a[data-for].active { border-bottom-color: #ccc; }
-            #counts { position:relative; display:block; width:100%; }
-            #toggleRealtime.pulse::before { top: 8px; }
+            .opcache-gui .nav-tab-list { border-bottom: 0; }
+            .opcache-gui .nav-tab { display: block; margin: 0; }
+            .opcache-gui .nav-tab-link { display: block; margin: 0 10px; padding: 10px 0 10px 30px; border: 0; }
+            .opcache-gui .nav-tab-link[data-for].active { border-bottom-color: #ccc; }
+            .opcache-gui .tab-content-overview-info { margin-right:auto; clear:both; }
+            .opcache-gui .tab-content-overview-counts { position:relative; display:block; width:100%; }
+            .opcache-gui .nav-tab-link-realtime.pulse::before { top: 8px; }
         }
         }
         @media screen and (max-width: 550px) {
         @media screen and (max-width: 550px) {
-            #frmFilter { width: 100%; }
+            .opcache-gui .file-filter { width: 100%; }
         }
         }
         @keyframes pulse {
         @keyframes pulse {
             0% {transform: scale(1); opacity: 0;}
             0% {transform: scale(1); opacity: 0;}
@@ -392,34 +390,34 @@ $opcache = OpCacheService::init($options);
     </style>
     </style>
 </head>
 </head>
 
 
-<body>
+<body class="opcache-gui">
 
 
 <header>
 <header>
-    <nav>
-        <ul>
-            <li><a data-for="overview" href="#overview" class="active">Overview</a></li>
+    <nav class="main-nav">
+        <ul class="nav-tab-list">
+            <li class="nav-tab"><a data-for="overview" href="#overview" class="active nav-tab-link">Overview</a></li>
             <?php if ($opcache->getOption('allow_filelist')): ?>
             <?php if ($opcache->getOption('allow_filelist')): ?>
-            <li><a data-for="files" href="#files">File usage</a></li>
+            <li class="nav-tab"><a data-for="files" href="#files" class="nav-tab-link">File usage</a></li>
             <?php endif; ?>
             <?php endif; ?>
             <?php if ($opcache->getOption('allow_reset')): ?>
             <?php if ($opcache->getOption('allow_reset')): ?>
-            <li><a href="?reset=1" id="resetCache" onclick="return confirm('Are you sure you want to reset the cache?');">Reset cache</a></li>
+            <li class="nav-tab"><a href="?reset=1" id="resetCache" onclick="return confirm('Are you sure you want to reset the cache?');" class="nav-tab-link nav-tab-link-reset">Reset cache</a></li>
             <?php endif; ?>
             <?php endif; ?>
             <?php if ($opcache->getOption('allow_realtime')): ?>
             <?php if ($opcache->getOption('allow_realtime')): ?>
-            <li><a href="#" id="toggleRealtime">Enable real-time update</a></li>
+            <li class="nav-tab"><a href="#" id="toggleRealtime" class="nav-tab-link nav-tab-link-realtime">Enable real-time update</a></li>
             <?php endif; ?>
             <?php endif; ?>
         </ul>
         </ul>
     </nav>
     </nav>
 </header>
 </header>
 
 
-<div id="tabs">
-    <div id="overview">
-        <div class="container">
-            <div id="counts"></div>
-            <div id="info">
+<div id="tabs" class="tab-content-container">
+    <div id="overview" class="tab-content tab-content-overview">
+        <div>
+            <div id="counts" class="tab-content-overview-counts"></div>
+            <div id="info" class="tab-content-overview-info">
                 <div id="generalInfo"></div>
                 <div id="generalInfo"></div>
                 <div id="directives"></div>
                 <div id="directives"></div>
                 <div id="functions">
                 <div id="functions">
-                    <table>
+                    <table class="tables">
                         <thead>
                         <thead>
                             <tr><th>Available functions</th></tr>
                             <tr><th>Available functions</th></tr>
                         </thead>
                         </thead>
@@ -434,19 +432,19 @@ $opcache = OpCacheService::init($options);
             </div>
             </div>
         </div>
         </div>
     </div>
     </div>
-    <div id="files">
+    <div id="files" class="tab-content tab-content-files">
         <?php if ($opcache->getOption('allow_filelist')): ?>
         <?php if ($opcache->getOption('allow_filelist')): ?>
         <form action="#">
         <form action="#">
             <label for="frmFilter">Start typing to filter on script path</label><br>
             <label for="frmFilter">Start typing to filter on script path</label><br>
-            <input type="text" name="filter" id="frmFilter">
+            <input type="text" name="filter" id="frmFilter" class="file-filter">
         </form>
         </form>
         <?php endif; ?>
         <?php endif; ?>
-        <div class="container" id="filelist"></div>
+        <div id="filelist"></div>
     </div>
     </div>
 </div>
 </div>
 
 
-<footer>
-    <a href="https://github.com/amnuts/opcache-gui" target="_blank" title="opcache-gui (currently version <?php echo OpCacheService::VERSION; ?>) on GitHub">https://github.com/amnuts/opcache-gui - version <?php echo OpCacheService::VERSION; ?></a>
+<footer class="main-footer">
+    <a class="github-link" href="https://github.com/amnuts/opcache-gui" target="_blank" title="opcache-gui (currently version <?php echo OpCacheService::VERSION; ?>) on GitHub">https://github.com/amnuts/opcache-gui - version <?php echo OpCacheService::VERSION; ?></a>
 </footer>
 </footer>
 
 
 <script type="text/javascript">
 <script type="text/javascript">
@@ -634,7 +632,7 @@ $opcache = OpCacheService::init($options);
         },
         },
         render: function () {
         render: function () {
             if (this.props.chart == true) {
             if (this.props.chart == true) {
-                return React.createElement("canvas", { id: this.props.gaugeId, width: "250", height: "250", "data-value": this.props.value });
+                return React.createElement("canvas", { id: this.props.gaugeId, className: "graph-widget", width: "250", height: "250", "data-value": this.props.value });
             }
             }
             return React.createElement(
             return React.createElement(
                 "p",
                 "p",
@@ -657,15 +655,15 @@ $opcache = OpCacheService::init($options);
         render: function () {
         render: function () {
             return React.createElement(
             return React.createElement(
                 "div",
                 "div",
-                { className: "moreinfo" },
+                { className: "widget-panel" },
                 React.createElement(
                 React.createElement(
                     "h3",
                     "h3",
-                    null,
+                    { className: "widget-header" },
                     "memory usage"
                     "memory usage"
                 ),
                 ),
                 React.createElement(
                 React.createElement(
                     "div",
                     "div",
-                    null,
+                    { className: "widget-value widget-info" },
                     React.createElement(
                     React.createElement(
                         "p",
                         "p",
                         null,
                         null,
@@ -722,15 +720,15 @@ $opcache = OpCacheService::init($options);
         render: function () {
         render: function () {
             return React.createElement(
             return React.createElement(
                 "div",
                 "div",
-                { className: "moreinfo" },
+                { className: "widget-panel" },
                 React.createElement(
                 React.createElement(
                     "h3",
                     "h3",
-                    null,
+                    { className: "widget-header" },
                     "opcache statistics"
                     "opcache statistics"
                 ),
                 ),
                 React.createElement(
                 React.createElement(
                     "div",
                     "div",
-                    null,
+                    { className: "widget-value widget-info" },
                     React.createElement(
                     React.createElement(
                         "p",
                         "p",
                         null,
                         null,
@@ -806,15 +804,15 @@ $opcache = OpCacheService::init($options);
         render: function () {
         render: function () {
             return React.createElement(
             return React.createElement(
                 "div",
                 "div",
-                { className: "moreinfo" },
+                { className: "widget-panel" },
                 React.createElement(
                 React.createElement(
                     "h3",
                     "h3",
-                    null,
+                    { className: "widget-header" },
                     "interned strings usage"
                     "interned strings usage"
                 ),
                 ),
                 React.createElement(
                 React.createElement(
                     "div",
                     "div",
-                    null,
+                    { className: "widget-value widget-info" },
                     React.createElement(
                     React.createElement(
                         "p",
                         "p",
                         null,
                         null,
@@ -876,7 +874,7 @@ $opcache = OpCacheService::init($options);
             if (this.state.data == false) {
             if (this.state.data == false) {
                 return React.createElement(
                 return React.createElement(
                     "p",
                     "p",
-                    { id: "fileCacheOnly" },
+                    { "class": "file-cache-only" },
                     "You have ",
                     "You have ",
                     React.createElement(
                     React.createElement(
                         "i",
                         "i",
@@ -901,45 +899,45 @@ $opcache = OpCacheService::init($options);
 
 
             var memoryHighlight = this.state.highlight.memory ? React.createElement(
             var memoryHighlight = this.state.highlight.memory ? React.createElement(
                 "div",
                 "div",
-                null,
+                { className: "widget-panel" },
                 React.createElement(
                 React.createElement(
                     "h3",
                     "h3",
-                    null,
+                    { className: "widget-header" },
                     "memory"
                     "memory"
                 ),
                 ),
                 React.createElement(
                 React.createElement(
                     "p",
                     "p",
-                    null,
+                    { className: "widget-value" },
                     React.createElement(UsageGraph, { chart: this.state.chart, value: this.state.data.used_memory_percentage, gaugeId: "memoryUsageCanvas" })
                     React.createElement(UsageGraph, { chart: this.state.chart, value: this.state.data.used_memory_percentage, gaugeId: "memoryUsageCanvas" })
                 )
                 )
             ) : null;
             ) : null;
 
 
             var hitsHighlight = this.state.highlight.hits ? React.createElement(
             var hitsHighlight = this.state.highlight.hits ? React.createElement(
                 "div",
                 "div",
-                null,
+                { className: "widget-panel" },
                 React.createElement(
                 React.createElement(
                     "h3",
                     "h3",
-                    null,
+                    { className: "widget-header" },
                     "hit rate"
                     "hit rate"
                 ),
                 ),
                 React.createElement(
                 React.createElement(
                     "p",
                     "p",
-                    null,
+                    { className: "widget-value" },
                     React.createElement(UsageGraph, { chart: this.state.chart, value: this.state.data.hit_rate_percentage, gaugeId: "hitRateCanvas" })
                     React.createElement(UsageGraph, { chart: this.state.chart, value: this.state.data.hit_rate_percentage, gaugeId: "hitRateCanvas" })
                 )
                 )
             ) : null;
             ) : null;
 
 
             var keysHighlight = this.state.highlight.keys ? React.createElement(
             var keysHighlight = this.state.highlight.keys ? React.createElement(
                 "div",
                 "div",
-                null,
+                { className: "widget-panel" },
                 React.createElement(
                 React.createElement(
                     "h3",
                     "h3",
-                    null,
+                    { className: "widget-header" },
                     "keys"
                     "keys"
                 ),
                 ),
                 React.createElement(
                 React.createElement(
                     "p",
                     "p",
-                    null,
+                    { className: "widget-value" },
                     React.createElement(UsageGraph, { chart: this.state.chart, value: this.state.data.used_key_percentage, gaugeId: "keyUsageCanvas" })
                     React.createElement(UsageGraph, { chart: this.state.chart, value: this.state.data.used_key_percentage, gaugeId: "keyUsageCanvas" })
                 )
                 )
             ) : null;
             ) : null;
@@ -1009,7 +1007,7 @@ $opcache = OpCacheService::init($options);
             ) : '';
             ) : '';
             return React.createElement(
             return React.createElement(
                 "table",
                 "table",
-                null,
+                { className: "tables general-info-table" },
                 React.createElement(
                 React.createElement(
                     "thead",
                     "thead",
                     null,
                     null,
@@ -1139,7 +1137,7 @@ $opcache = OpCacheService::init($options);
             });
             });
             return React.createElement(
             return React.createElement(
                 "table",
                 "table",
-                null,
+                { className: "tables directives-table" },
                 React.createElement(
                 React.createElement(
                     "thead",
                     "thead",
                     null,
                     null,
@@ -1202,7 +1200,7 @@ $opcache = OpCacheService::init($options);
                             ",\xA0",
                             ",\xA0",
                             React.createElement(
                             React.createElement(
                                 "a",
                                 "a",
-                                { className: "metainfo", href: '?invalidate=' + file.full_path, "data-file": file.full_path, onClick: this.handleInvalidate },
+                                { className: "file-metainfo", href: '?invalidate=' + file.full_path, "data-file": file.full_path, onClick: this.handleInvalidate },
                                 "force file invalidation"
                                 "force file invalidation"
                             )
                             )
                         );
                         );
@@ -1214,18 +1212,13 @@ $opcache = OpCacheService::init($options);
                             "td",
                             "td",
                             null,
                             null,
                             React.createElement(
                             React.createElement(
-                                "div",
-                                null,
-                                React.createElement(
-                                    "span",
-                                    { className: "pathname" },
-                                    file.full_path
-                                ),
-                                React.createElement("br", null),
-                                React.createElement(FilesMeta, { data: [file.readable.hits, file.readable.memory_consumption, file.last_used] }),
-                                invalidate,
-                                invalidated
-                            )
+                                "span",
+                                { className: "file-pathname" },
+                                file.full_path
+                            ),
+                            React.createElement(FilesMeta, { data: [file.readable.hits, file.readable.memory_consumption, file.last_used] }),
+                            invalidate,
+                            invalidated
                         )
                         )
                     );
                     );
                 }.bind(this));
                 }.bind(this));
@@ -1235,7 +1228,7 @@ $opcache = OpCacheService::init($options);
                     React.createElement(FilesListed, { showing: this.state.showing }),
                     React.createElement(FilesListed, { showing: this.state.showing }),
                     React.createElement(
                     React.createElement(
                         "table",
                         "table",
-                        null,
+                        { className: "tables file-list-table" },
                         React.createElement(
                         React.createElement(
                             "thead",
                             "thead",
                             null,
                             null,
@@ -1266,7 +1259,7 @@ $opcache = OpCacheService::init($options);
         render: function () {
         render: function () {
             return React.createElement(
             return React.createElement(
                 "span",
                 "span",
-                { className: "metainfo" },
+                { className: "file-metainfo" },
                 React.createElement(
                 React.createElement(
                     "b",
                     "b",
                     null,
                     null,

+ 29 - 31
src/status.jsx

@@ -17,7 +17,7 @@ var UsageGraph = React.createClass({
     },
     },
     render: function() {
     render: function() {
         if (this.props.chart == true) {
         if (this.props.chart == true) {
-            return(<canvas id={this.props.gaugeId} width="250" height="250" data-value={this.props.value} />);
+            return(<canvas id={this.props.gaugeId} className="graph-widget" width="250" height="250" data-value={this.props.value} />);
         }
         }
         return(<p><span className="large">{this.props.value}</span><span>%</span></p>);
         return(<p><span className="large">{this.props.value}</span><span>%</span></p>);
     }
     }
@@ -26,9 +26,9 @@ var UsageGraph = React.createClass({
 var MemoryUsagePanel = React.createClass({
 var MemoryUsagePanel = React.createClass({
     render: function() {
     render: function() {
         return (
         return (
-            <div className="moreinfo">
-                <h3>memory usage</h3>
-                <div>
+            <div className="widget-panel">
+                <h3 className="widget-header">memory usage</h3>
+                <div className="widget-value widget-info">
                     <p><b>total memory:</b> {this.props.total}</p>
                     <p><b>total memory:</b> {this.props.total}</p>
                     <p><b>used memory:</b> {this.props.used}</p>
                     <p><b>used memory:</b> {this.props.used}</p>
                     <p><b>free memory:</b> {this.props.free}</p>
                     <p><b>free memory:</b> {this.props.free}</p>
@@ -42,9 +42,9 @@ var MemoryUsagePanel = React.createClass({
 var StatisticsPanel = React.createClass({
 var StatisticsPanel = React.createClass({
     render: function() {
     render: function() {
         return (
         return (
-            <div className="moreinfo">
-                <h3>opcache statistics</h3>
-                <div>
+            <div className="widget-panel">
+                <h3 className="widget-header">opcache statistics</h3>
+                <div className="widget-value widget-info">
                     <p><b>number of cached files:</b> {this.props.num_cached_scripts}</p>
                     <p><b>number of cached files:</b> {this.props.num_cached_scripts}</p>
                     <p><b>number of hits:</b> {this.props.hits}</p>
                     <p><b>number of hits:</b> {this.props.hits}</p>
                     <p><b>number of misses:</b> {this.props.misses}</p>
                     <p><b>number of misses:</b> {this.props.misses}</p>
@@ -60,9 +60,9 @@ var StatisticsPanel = React.createClass({
 var InternedStringsPanel = React.createClass({
 var InternedStringsPanel = React.createClass({
     render: function() {
     render: function() {
         return (
         return (
-            <div className="moreinfo">
-                <h3>interned strings usage</h3>
-                <div>
+            <div className="widget-panel">
+                <h3 className="widget-header">interned strings usage</h3>
+                <div className="widget-value widget-info">
                     <p><b>buffer size:</b> {this.props.buffer_size}</p>
                     <p><b>buffer size:</b> {this.props.buffer_size}</p>
                     <p><b>used memory:</b> {this.props.strings_used_memory}</p>
                     <p><b>used memory:</b> {this.props.strings_used_memory}</p>
                     <p><b>free memory:</b> {this.props.strings_free_memory}</p>
                     <p><b>free memory:</b> {this.props.strings_free_memory}</p>
@@ -84,7 +84,7 @@ var OverviewCounts = React.createClass({
     render: function() {
     render: function() {
         if (this.state.data == false) {
         if (this.state.data == false) {
             return (
             return (
-                <p id="fileCacheOnly">
+                <p class="file-cache-only">
                     You have <i>opcache.file_cache_only</i> turned on.  As a result, the memory information is not available.  Statistics and file list may also not be returned by <i>opcache_get_statistics()</i>.
                     You have <i>opcache.file_cache_only</i> turned on.  As a result, the memory information is not available.  Statistics and file list may also not be returned by <i>opcache_get_statistics()</i>.
                 </p>
                 </p>
             );
             );
@@ -100,23 +100,23 @@ var OverviewCounts = React.createClass({
         );
         );
 
 
         var memoryHighlight = this.state.highlight.memory ? (
         var memoryHighlight = this.state.highlight.memory ? (
-                <div>
-                    <h3>memory</h3>
-                    <p><UsageGraph chart={this.state.chart} value={this.state.data.used_memory_percentage} gaugeId="memoryUsageCanvas"/></p>
+                <div className="widget-panel">
+                    <h3 className="widget-header">memory</h3>
+                    <p className="widget-value"><UsageGraph chart={this.state.chart} value={this.state.data.used_memory_percentage} gaugeId="memoryUsageCanvas"/></p>
                 </div>
                 </div>
             ) : null;
             ) : null;
 
 
         var hitsHighlight = this.state.highlight.hits ? (
         var hitsHighlight = this.state.highlight.hits ? (
-                <div>
-                    <h3>hit rate</h3>
-                    <p><UsageGraph chart={this.state.chart} value={this.state.data.hit_rate_percentage} gaugeId="hitRateCanvas"/></p>
+                <div className="widget-panel">
+                    <h3 className="widget-header">hit rate</h3>
+                    <p className="widget-value"><UsageGraph chart={this.state.chart} value={this.state.data.hit_rate_percentage} gaugeId="hitRateCanvas"/></p>
                 </div>
                 </div>
             ) : null;
             ) : null;
 
 
         var keysHighlight = this.state.highlight.keys ? (
         var keysHighlight = this.state.highlight.keys ? (
-                <div>
-                    <h3>keys</h3>
-                    <p><UsageGraph chart={this.state.chart} value={this.state.data.used_key_percentage} gaugeId="keyUsageCanvas"/></p>
+                <div className="widget-panel">
+                    <h3 className="widget-header">keys</h3>
+                    <p className="widget-value"><UsageGraph chart={this.state.chart} value={this.state.data.used_key_percentage} gaugeId="keyUsageCanvas"/></p>
                 </div>
                 </div>
             ) : null;
             ) : null;
 
 
@@ -163,7 +163,7 @@ var GeneralInfo = React.createClass({
             ? <tr><td>Last reset</td><td>{this.state.reset}</td></tr>
             ? <tr><td>Last reset</td><td>{this.state.reset}</td></tr>
             : '';
             : '';
         return (
         return (
-            <table>
+            <table className="tables general-info-table">
                 <thead>
                 <thead>
                     <tr><th colSpan="2">General info</th></tr>
                     <tr><th colSpan="2">General info</th></tr>
                 </thead>
                 </thead>
@@ -213,7 +213,7 @@ var Directives = React.createClass({
             );
             );
         });
         });
         return (
         return (
-            <table>
+            <table className="tables directives-table">
                 <thead>
                 <thead>
                     <tr><th colSpan="2">Directives</th></tr>
                     <tr><th colSpan="2">Directives</th></tr>
                 </thead>
                 </thead>
@@ -249,18 +249,16 @@ var Files = React.createClass({
                     invalidated = <span><i className="invalid metainfo"> - has been invalidated</i></span>;
                     invalidated = <span><i className="invalid metainfo"> - has been invalidated</i></span>;
                 }
                 }
                 if (canInvalidate) {
                 if (canInvalidate) {
-                    invalidate = <span>,&nbsp;<a className="metainfo" href={'?invalidate='
+                    invalidate = <span>,&nbsp;<a className="file-metainfo" href={'?invalidate='
                         + file.full_path} data-file={file.full_path} onClick={this.handleInvalidate}>force file invalidation</a></span>;
                         + file.full_path} data-file={file.full_path} onClick={this.handleInvalidate}>force file invalidation</a></span>;
                 }
                 }
                 return (
                 return (
                     <tr key={file.full_path} data-path={file.full_path.toLowerCase()} className={i%2?'alternate':''}>
                     <tr key={file.full_path} data-path={file.full_path.toLowerCase()} className={i%2?'alternate':''}>
                         <td>
                         <td>
-                            <div>
-                                <span className="pathname">{file.full_path}</span><br/>
-                                <FilesMeta data={[file.readable.hits, file.readable.memory_consumption, file.last_used]} />
-                                {invalidate}
-                                {invalidated}
-                            </div>
+                            <span className="file-pathname">{file.full_path}</span>
+                            <FilesMeta data={[file.readable.hits, file.readable.memory_consumption, file.last_used]} />
+                            {invalidate}
+                            {invalidated}
                         </td>
                         </td>
                     </tr>
                     </tr>
                 );
                 );
@@ -268,7 +266,7 @@ var Files = React.createClass({
             return (
             return (
                 <div>
                 <div>
                     <FilesListed showing={this.state.showing}/>
                     <FilesListed showing={this.state.showing}/>
-                    <table>
+                    <table className="tables file-list-table">
                         <thead>
                         <thead>
                         <tr>
                         <tr>
                             <th>Script</th>
                             <th>Script</th>
@@ -287,7 +285,7 @@ var Files = React.createClass({
 var FilesMeta = React.createClass({
 var FilesMeta = React.createClass({
     render: function() {
     render: function() {
         return (
         return (
-            <span className="metainfo">
+            <span className="file-metainfo">
                 <b>hits: </b><span>{this.props.data[0]}, </span>
                 <b>hits: </b><span>{this.props.data[0]}, </span>
                 <b>memory: </b><span>{this.props.data[1]}, </span>
                 <b>memory: </b><span>{this.props.data[1]}, </span>
                 <b>last used: </b><span>{this.props.data[2]}</span>
                 <b>last used: </b><span>{this.props.data[2]}</span>