From adbd212660761dbb0d1ab216e12bb87f3f373183 Mon Sep 17 00:00:00 2001
From: Patrick Jentsch <p.jentsch@uni-bielefeld.de>
Date: Thu, 27 May 2021 13:05:46 +0200
Subject: [PATCH] Update color scheme definition and some codestyle
 enhancements

---
 web/app/services/__init__.py                  |   2 +-
 web/app/services/forms.py                     |   4 +-
 web/app/services/views.py                     |   6 +-
 web/app/static/css/material_icons.css         |   1 -
 .../static/css/materialize.sticky-footer.css  |  13 ---
 web/app/static/css/nopaque.css                |  78 ++++---------
 web/app/static/css/nopaque_icons.css          |  56 ---------
 ...ze.sidenav-fixed.css => sidenav_fixed.css} |   0
 .../js/nopaque/RessourceLists/CorpusList.js   |   2 +-
 .../js/nopaque/RessourceLists/JobList.js      |   2 +-
 web/app/templates/_color.html.j2              | 110 ++++++++++++++++++
 web/app/templates/_colors.html.j2             |  15 ---
 web/app/templates/admin/edit_user.html.j2     |   2 +-
 web/app/templates/auth/login.html.j2          |   2 +-
 web/app/templates/auth/register.html.j2       |   2 +-
 web/app/templates/auth/reset_password.html.j2 |   2 +-
 .../auth/reset_password_request.html.j2       |   2 +-
 web/app/templates/corpora/add_corpus.html.j2  |   8 +-
 .../templates/corpora/add_corpus_file.html.j2 |   8 +-
 .../templates/corpora/analyse_corpus.html.j2  |   8 +-
 web/app/templates/corpora/corpus.html.j2      |   9 +-
 web/app/templates/corpora/corpus_file.html.j2 |   8 +-
 .../templates/corpora/import_corpus.html.j2   |  10 +-
 .../corpora/interactions/display.html.j2      |   2 +-
 .../query_results/add_query_result.html.j2    |   8 +-
 .../corpora/query_results/inspect.html.j2     |   9 +-
 .../query_results/query_result.html.j2        |   6 +-
 web/app/templates/jobs/job.html.j2            |  15 +--
 web/app/templates/main/dashboard.html.j2      |  18 +--
 web/app/templates/main/index.html.j2          |  18 +--
 web/app/templates/nopaque.html.j2             |  92 +++------------
 .../services/corpus_analysis.html.j2          |   8 +-
 ...{file-setup.html.j2 => file_setup.html.j2} |  12 +-
 web/app/templates/services/nlp.html.j2        |  12 +-
 web/app/templates/services/ocr.html.j2        |  12 +-
 .../settings/change_password.html.j2          |   2 +-
 .../settings/edit_general_settings.html.j2    |   2 +-
 .../edit_notification_settings.html.j2        |   2 +-
 38 files changed, 216 insertions(+), 352 deletions(-)
 delete mode 100644 web/app/static/css/materialize.sticky-footer.css
 rename web/app/static/css/{materialize.sidenav-fixed.css => sidenav_fixed.css} (100%)
 create mode 100644 web/app/templates/_color.html.j2
 delete mode 100644 web/app/templates/_colors.html.j2
 rename web/app/templates/services/{file-setup.html.j2 => file_setup.html.j2} (85%)

diff --git a/web/app/services/__init__.py b/web/app/services/__init__.py
index 6732fd88..ef3c3ed2 100644
--- a/web/app/services/__init__.py
+++ b/web/app/services/__init__.py
@@ -5,7 +5,7 @@ SERVICES = {
     'corpus_analysis': {
         'name': 'Corpus analysis'
     },
-    'file-setup': {
+    'file_setup': {
         'name': 'File setup',
         'versions': {
             'latest': '1.0.0b',
diff --git a/web/app/services/forms.py b/web/app/services/forms.py
index 5d9f5ede..aba0b8c3 100644
--- a/web/app/services/forms.py
+++ b/web/app/services/forms.py
@@ -77,7 +77,7 @@ class AddFileSetupJobForm(AddJobForm):
                                       '| .tif')
 
     def __init__(self, *args, **kwargs):
-        version = kwargs.pop('version', SERVICES['file-setup']['versions']['latest'])
+        version = kwargs.pop('version', SERVICES['file_setup']['versions']['latest'])
         super().__init__(*args, **kwargs)
-        self.version.choices = [(x, x) for x in SERVICES['file-setup']['versions'] if x != 'latest']  # noqa
+        self.version.choices = [(x, x) for x in SERVICES['file_setup']['versions'] if x != 'latest']  # noqa
         self.version.default = version
diff --git a/web/app/services/views.py b/web/app/services/views.py
index 4aaac006..d83921d2 100644
--- a/web/app/services/views.py
+++ b/web/app/services/views.py
@@ -20,18 +20,18 @@ def service(service):
     if service == 'corpus_analysis':
         return render_template('services/{}.html.j2'.format(service),
                                title=SERVICES[service]['name'])
-    elif service == 'file-setup':
+    elif service == 'file_setup':
         form = AddFileSetupJobForm(prefix='add-file-setup-job-form')
     elif service == 'nlp':
         version = request.args.get('version')
-        if version is None or version not in SERVICES['nlp']['versions']:
+        if version is None or version not in SERVICES[service]['versions']:
             form = AddNLPJobForm(prefix='add-nlp-job-form')
         else:
             form = AddNLPJobForm(prefix='add-nlp-job-form', version=version)
             form.version.data = version
     elif service == 'ocr':
         version = request.args.get('version')
-        if version is None or version not in SERVICES['ocr']['versions']:
+        if version is None or version not in SERVICES[service]['versions']:
             form = AddOCRJobForm(prefix='add-ocr-job-form')
         else:
             form = AddOCRJobForm(prefix='add-ocr-job-form', version=version)
diff --git a/web/app/static/css/material_icons.css b/web/app/static/css/material_icons.css
index 0e5303b5..6590c25c 100644
--- a/web/app/static/css/material_icons.css
+++ b/web/app/static/css/material_icons.css
@@ -4,7 +4,6 @@
   font-family: 'Material Icons';
   font-style: normal;
   font-weight: 400;
-  src: url(../fonts/material_icons/MaterialIcons-Regular.eot); /* For IE6-8 */
   src: local('Material Icons'),
     local('MaterialIcons-Regular'),
     url(../fonts/material_icons/MaterialIcons-Regular.ttf) format('truetype'),
diff --git a/web/app/static/css/materialize.sticky-footer.css b/web/app/static/css/materialize.sticky-footer.css
deleted file mode 100644
index 49b8f5b8..00000000
--- a/web/app/static/css/materialize.sticky-footer.css
+++ /dev/null
@@ -1,13 +0,0 @@
-/*
- * Force the footer to always stay on the bottom of the page regardless of how
- * little content is on the page.
- */
-body {
-  display: flex;
-  min-height: 100vh;
-  flex-direction: column;
-}
-
-main {
-  flex: 1 0 auto;
-}
diff --git a/web/app/static/css/nopaque.css b/web/app/static/css/nopaque.css
index 3bf1b42c..de92409f 100644
--- a/web/app/static/css/nopaque.css
+++ b/web/app/static/css/nopaque.css
@@ -1,6 +1,6 @@
 /* Fix material icon vertical alignment when nested in various elements */
-h1 .material-icons, h2 .material-icons, h3 .material-icons, h4 .material-icons,
-.tab .material-icons {
+h1 .nopaque-icons, h2 .nopaque-icons, h3 .nopaque-icons, h4 .nopaque-icons,
+.tab .nopaque-icons, .tab .material-icons {
   line-height: inherit;
 }
 
@@ -8,12 +8,27 @@ main {
   margin-top: 48px;
 }
 
+/*
+ * Force the footer to always stay on the bottom of the page regardless of how
+ * little content is on the page.
+ */
+body {
+  display: flex;
+  min-height: 100vh;
+  flex-direction: column;
+}
+
+main {
+  flex: 1 0 auto;
+}
+
+
 table.ressource-list tr {
   cursor: pointer;
 }
 
 .parallax-container .parallax {
-  z-index: auto;
+  z-index: 0;
 }
 
 /* add custom bold class */
@@ -117,66 +132,19 @@ indicator will show up how the column is sorted right now.; */
   cursor: pointer;
 }
 
-/* styles for resource lists */
-.analyse-link[href=""] {
-  display: none;
-}
-
 .btn-scale-x2 {
   transform: scale(2);
 }
 
-.btn-scale-x2 .service-icon {
+.btn-scale-x2 .nopaque-icons.service-icon {
   font-size: 2.5rem;
 }
 
-.service-icon[data-service]:before {
-  content: "help";
-}
-.service-icon[data-service="corpus-analysis"]:before {
-  content: "H";
-}
-.service-icon[data-service="file-setup"]:before {
-  content: "E";
-}
-.service-icon[data-service="nlp"]:before {
-  content: "G";
-}
-.service-icon[data-service="ocr"]:before {
-  content: "F";
-}
+.nopaque-icons.service-icon[data-service="corpus-analysis"]:empty:before {content: "H";}
+.nopaque-icons.service-icon[data-service="file-setup"]:empty:before {content: "E";}
+.nopaque-icons.service-icon[data-service="nlp"]:empty:before {content: "G";}
+.nopaque-icons.service-icon[data-service="ocr"]:empty:before {content: "F";}
 
 .status-text[data-status]:before {
   content: attr(data-status);
 }
-
-.status-color[data-status] {
-  background-color: #f44336 !important; /* ~materialize "red" */
-}
-.status-color[data-status="unprepared"] {
-  background-color: #9e9e9e !important; /* ~materialize grey */
-}
-.status-color[data-status="submitted"] {
-  background-color: #9e9e9e !important; /* ~materialize grey */
-}
-.status-color[data-status="queued"] {
-  background-color: #2196f3 !important; /* ~materialize blue */
-}
-.status-color[data-status="running"] {
-  background-color: #ffc107 !important; /* ~materialize amber */
-}
-.status-color[data-status="complete"] {
-  background-color: #4caf50 !important; /* ~materialize green */
-}
-.status-color[data-status="prepared"] {
-  background-color: #4caf50 !important; /* ~materialize green */
-}
-.status-color[data-status="start analysis"] {
-  background-color: #2196f3 !important; /* ~materialize blue */
-}
-.status-color[data-status="analysing"] {
-  background-color: #4caf50 !important; /* ~materialize green */
-}
-.status-color[data-status="stop analysis"] {
-  background-color: #ff5722 !important; /* ~materialize deep-orange */
-}
diff --git a/web/app/static/css/nopaque_icons.css b/web/app/static/css/nopaque_icons.css
index 395b8bc6..f3e49752 100644
--- a/web/app/static/css/nopaque_icons.css
+++ b/web/app/static/css/nopaque_icons.css
@@ -1,5 +1,3 @@
-/* https://google.github.io/material-design-icons/#setup-method-2-self-hosting */
-
 @font-face {
   font-family: 'nopaque Icons';
   font-style: normal;
@@ -33,57 +31,3 @@
   /* Support for IE. */
   font-feature-settings: 'liga';
 }
-
-.breadcrumb i.nopaque-icons {
-  display: inline-block;
-  float: left;
-  font-size: 24px;
-}
-
-.nopaque-icons {
-  text-rendering: optimizeLegibility;
-  -webkit-font-feature-settings: 'liga';
-     -moz-font-feature-settings: 'liga';
-          font-feature-settings: 'liga';
-}
-
-nav i.nopaque-icons {
-  display: block;
-  font-size: 24px;
-  height: 56px;
-  line-height: 56px;
-}
-
-nav .brand-logo i.nopaque-icons {
-  float: left;
-  margin-right: 15px;
-}
-
-nav ul a.btn > .nopaque-icons, nav ul a.btn-large > .nopaque-icons, nav ul a.btn-small > .nopaque-icons, nav ul a.btn-large > .nopaque-icons, nav ul a.btn-flat > .nopaque-icons, nav ul a.btn-floating > .nopaque-icons {
-  height: inherit;
-  line-height: inherit;
-}
-
-.input-field input[type=search]:focus:not(.browser-default) ~ .nopaque-icons {
-  color: #444;
-}
-
-.input-field input[type=search] ~ .nopaque-icons {
-  position: absolute;
-  top: 0;
-  right: 1rem;
-  color: transparent;
-  cursor: pointer;
-  font-size: 2rem;
-  -webkit-transition: .3s color;
-  transition: .3s color;
-}
-
-.sidenav li > a > i.nopaque-icons {
-  float: left;
-  height: 48px;
-  line-height: 48px;
-  margin: 0 32px 0 0;
-  width: 24px;
-  color: rgba(0, 0, 0, 0.54);
-}
diff --git a/web/app/static/css/materialize.sidenav-fixed.css b/web/app/static/css/sidenav_fixed.css
similarity index 100%
rename from web/app/static/css/materialize.sidenav-fixed.css
rename to web/app/static/css/sidenav_fixed.css
diff --git a/web/app/static/js/nopaque/RessourceLists/CorpusList.js b/web/app/static/js/nopaque/RessourceLists/CorpusList.js
index 0d5b2eb7..fadb4fa1 100644
--- a/web/app/static/js/nopaque/RessourceLists/CorpusList.js
+++ b/web/app/static/js/nopaque/RessourceLists/CorpusList.js
@@ -81,7 +81,7 @@ class CorpusList extends RessourceList {
 }
 CorpusList.options = {
   item: `<tr>
-           <td><a class="btn-floating disabled"><i class="material-icons service-color" data-service="corpus-analysis">book</i></a></td>
+           <td><a class="btn-floating disabled"><i class="material-icons service-color darken" data-service="corpus-analysis">book</i></a></td>
            <td><b class="title"></b><br><i class="description"></i></td>
            <td><span class="badge new status status-color status-text" data-badge-caption=""></span></td>
            <td class="right-align">
diff --git a/web/app/static/js/nopaque/RessourceLists/JobList.js b/web/app/static/js/nopaque/RessourceLists/JobList.js
index b4c47504..cb88b1e3 100644
--- a/web/app/static/js/nopaque/RessourceLists/JobList.js
+++ b/web/app/static/js/nopaque/RessourceLists/JobList.js
@@ -82,7 +82,7 @@ class JobList extends RessourceList {
 }
 JobList.options = {
   item: `<tr>
-           <td><a class="btn-floating disabled"><i class="nopaque-icons service service-color service-icon"></i></a></td>
+           <td><a class="btn-floating disabled"><i class="nopaque-icons service service-color darken service-icon"></i></a></td>
            <td><b class="title"></b><br><i class="description"></i></td>
            <td><span class="badge new status status-color status-text" data-badge-caption=""></span></td>
            <td class="right-align">
diff --git a/web/app/templates/_color.html.j2 b/web/app/templates/_color.html.j2
new file mode 100644
index 00000000..e4f2b1bf
--- /dev/null
+++ b/web/app/templates/_color.html.j2
@@ -0,0 +1,110 @@
+{% set colors = {
+  'primary': '#00426f',
+  'primary_variant': '#1A5C89',
+  'secondary': '#00426f',
+  'secondary_variant': '#1A5C89',
+  'background': '#ffffff',
+  'surface': '#ffffff',
+  'error': '#b00020',
+
+  'service_corpus_analysis': '#aa9cc9',
+  'service_corpus_analysis_darken': '#6b3f89',
+  'service_corpus_analysis_lighten': '#ebe8f6',
+  'service_file_setup': '#d5dc95',
+  'service_file_setup_darken': '#a1b300',
+  'service_file_setup_lighten': '#f2f3e1',
+  'service_nlp': '#98acd2',
+  'service_nlp_darken': '#0064a3',
+  'service_nlp_lighten': '#e5e8f5',
+  'service_ocr': '#a9d8c8',
+  'service_ocr_darken': '#00a58b',
+  'service_ocr_lighten': '#e7f4f1',
+
+  'status_unprepared': '#9e9e9e',
+  'status_submitted': '#9e9e9e',
+  'status_queued': '#2196f3',
+  'status_running': '#ffc107',
+  'status_complete': '#4caf50',
+  'status_failed': '#f44336',
+  'status_prepared': '#4caf50',
+  'status_start_analysis': '#2196f3',
+  'status_analysing': '#4caf50',
+  'status_stop_analysis': '#ff5722'
+} %}
+
+
+<style>
+  .primary-color {background-color: {{ colors['primary'] }} !important;}
+  .primary-color-border {border-color: {{ colors['primary'] }} !important;}
+  .primary-color-text {color: {{ colors['primary'] }} !important;}
+  .primary-variant-color {background-color: {{ colors['primary_variant'] }} !important;}
+  .primary-variant-color-border {border-color: {{ colors['primary_variant'] }} !important;}
+  .primary-variant-color-text {color: {{ colors['primary_variant'] }} !important;}
+
+  .secondary-color {background-color: {{ colors['secondary'] }} !important;}
+  .secondary-color-border {border-color: {{ colors['secondary'] }} !important;}
+  .secondary-color-text {color: {{ colors['secondary'] }} !important;}
+  .secondary-variant-color {background-color: {{ colors['secondary_variant'] }} !important;}
+  .secondary-variant-color-border {border-color: {{ colors['secondary_variant'] }} !important;}
+  .secondary-variant-color-text {color: {{ colors['secondary_variant'] }} !important;}
+
+  .background-color {background-color: {{ colors['background'] }} !important;}
+  .background-color-border {border-color: {{ colors['background'] }} !important;}
+  .background-color-text {color: {{ colors['background'] }} !important;}
+
+  .surface-color {background-color: {{ colors['surface'] }} !important;}
+  .surface-color-border {border-color: {{ colors['surface'] }} !important;}
+  .surface-color-text {color: {{ colors['surface'] }} !important;}
+
+  .error-color {background-color: {{ colors['error'] }} !important;}
+  .error-color-border {border-color: {{ colors['error'] }} !important;}
+  .error-color-text {color: {{ colors['error'] }} !important;}
+
+  main {background-color: {{ colors['background'] }};}
+  main .btn, main .btn-small, main .btn-large, main .btn-floating {background-color: {{ colors['secondary'] }};}
+  main .btn:hover, main .btn-large:hover, main .btn-small:hover, main .btn-floating:hover {background-color: {{ colors['secondary_variant'] }};}
+  main .pagination li.active {background-color: {{ colors['secondary'] }};}
+  main .table-of-contents a.active {border-color: {{ colors['secondary'] }};}
+  main .tabs .tab a {color: inherit;}
+  main .tabs .tab.disabled a, main .tabs .tab.disabled a:hover {color: {{ colors['secondary'] }}28;}
+  main .tabs .tab a:hover {color: {{ colors['secondary'] }};}
+  main .tabs .tab a.active, main .tabs .tab a:focus.active {color: {{ colors['secondary'] }}; background-color: {{ colors['secondary'] }}28;}
+  main .tabs .indicator {background-color: {{ colors['secondary'] }};}
+
+  {% for service in ['file-setup', 'ocr', 'nlp', 'corpus-analysis'] %}
+  {% set service_color = colors['service_' + service.replace('-', '_')] %}
+  {% set service_color_darken = colors['service_' + service.replace('-', '_') + '_darken'] %}
+  {% set service_color_lighten = colors['service_' + service.replace('-', '_') + '_lighten'] %}
+  .service-scheme[data-service="{{ service }}"] {background-color: {{ service_color_lighten }};}
+  .service-scheme[data-service="{{ service }}"] .btn, .service-scheme[data-service="{{ service }}"] .btn-small, .service-scheme[data-service="{{ service }}"] .btn-large, .service-scheme[data-service="{{ service }}"] .btn-floating {background-color: {{ service_color_darken }};}
+  .service-scheme[data-service="{{ service }}"] .btn:hover, .service-scheme[data-service="{{ service }}"] .btn-large:hover, .service-scheme[data-service="{{ service }}"] .btn-small:hover, .service-scheme[data-service="{{ service }}"] .btn-floating:hover {background-color: {{ service_color }};}
+  .service-scheme[data-service="{{ service }}"] .pagination li.active {background-color: {{ service_color_darken }};}
+  .service-scheme[data-service="{{ service }}"] .table-of-contents a.active {border-color: {{ service_color_darken }};}
+  .service-scheme[data-service="{{ service }}"] .tabs .tab a {color: inherit;}
+  .service-scheme[data-service="{{ service }}"] .tabs .tab.disabled a, .service-scheme[data-service="{{ service }}"] .tabs .tab.disabled a:hover {color: {{ service_color_darken }}28;}
+  .service-scheme[data-service="{{ service }}"] .tabs .tab a:hover {color: {{ service_color_darken }};}
+  .service-scheme[data-service="{{ service }}"] .tabs .tab a.active, .service-scheme[data-service="{{ service }}"] .tabs .tab a:focus.active {color: {{ service_color_darken }}; background-color: {{ service_color_darken }}28;}
+  .service-scheme[data-service="{{ service }}"] .tabs .indicator {background-color: {{ service_color_darken }};}
+
+  .service-color[data-service="{{ service }}"] {background-color: {{ service_color }} !important;}
+  .service-color-text[data-service="{{ service }}"] {color: {{ service_color }} !important;}
+  .service-color-border[data-service="{{ service }}"] {border-color: {{ service_color }} !important;}
+  .service-color[data-service="{{ service }}"].darken {background-color: {{ service_color_darken }} !important;}
+  .service-color-text[data-service="{{ service }}"].text-darken {color: {{ service_color_darken }} !important;}
+  .service-color-border[data-service="{{ service }}"].border-darken {border-color: {{ service_color_darken }} !important;}
+  .service-color[data-service="{{ service }}"].lighten {background-color: {{ service_color_lighten }} !important;}
+  .service-color-text[data-service="{{ service }}"].text-lighten {color: {{ service_color_lighten }} !important;}
+  .service-color-border[data-service="{{ service }}"].border-lighten {border-color: {{ service_color_lighten }} !important;}
+  {% endfor %}
+
+  .status-color[data-status="unprepared"] {background-color: {{ colors.status_unprepared }} !important;}
+  .status-color[data-status="submitted"] {background-color: {{ colors.status_submitted }} !important;}
+  .status-color[data-status="queued"] {background-color: {{ colors.status_queued }} !important;}
+  .status-color[data-status="running"] {background-color: {{ colors.status_running }} !important;}
+  .status-color[data-status="complete"] {background-color: {{ colors.status_complete }} !important;}
+  .status-color[data-status="failed"] {background-color: {{ colors.status_failed }} !important;}
+  .status-color[data-status="prepared"] {background-color: {{ colors.status_prepared }} !important;}
+  .status-color[data-status="start analysis"] {background-color: {{ colors.status_start_analysis }} !important;}
+  .status-color[data-status="analysing"] {background-color: {{ colors.status_analysing }} !important;}
+  .status-color[data-status="stop analysis"] {background-color: {{ colors.status_stop_analysis }} !important;}
+</style>
diff --git a/web/app/templates/_colors.html.j2 b/web/app/templates/_colors.html.j2
deleted file mode 100644
index be667210..00000000
--- a/web/app/templates/_colors.html.j2
+++ /dev/null
@@ -1,15 +0,0 @@
-{% set colors = {'primary': '#00426f',
-                 'secondary': '#1A5C89',
-                 'footer': '#b1b3b4',
-                 'corpus_analysis': '#aa9cc9',
-                 'corpus_analysis_darken': '#6b3f89',
-                 'corpus_analysis_lighten': '#ebe8f6',
-                 'file_setup': '#d5dc95',
-                 'file_setup_darken': '#a1b300',
-                 'file_setup_lighten': '#f2f3e1',
-                 'nlp': '#98acd2',
-                 'nlp_darken': '#0064a3',
-                 'nlp_lighten': '#e5e8f5',
-                 'ocr': '#a9d8c8',
-                 'ocr_darken': '#00a58b',
-                 'ocr_lighten': '#e7f4f1'} %}
diff --git a/web/app/templates/admin/edit_user.html.j2 b/web/app/templates/admin/edit_user.html.j2
index 61ef21da..5f441cf2 100644
--- a/web/app/templates/admin/edit_user.html.j2
+++ b/web/app/templates/admin/edit_user.html.j2
@@ -1,5 +1,5 @@
 {% extends "nopaque.html.j2" %}
-{% import 'materialize/wtf.html.j2' as wtf %}
+{% import "materialize/wtf.html.j2" as wtf %}
 
 {% block nav_content %}
 {% include 'admin/_breadcrumbs.html.j2' %}
diff --git a/web/app/templates/auth/login.html.j2 b/web/app/templates/auth/login.html.j2
index db83e8b0..c2133616 100644
--- a/web/app/templates/auth/login.html.j2
+++ b/web/app/templates/auth/login.html.j2
@@ -1,5 +1,5 @@
 {% extends "nopaque.html.j2" %}
-{% import 'materialize/wtf.html.j2' as wtf %}
+{% import "materialize/wtf.html.j2" as wtf %}
 
 {% block nav_content %}
 {% include 'auth/_breadcrumbs.html.j2' %}
diff --git a/web/app/templates/auth/register.html.j2 b/web/app/templates/auth/register.html.j2
index 7b8db08d..111b36ad 100644
--- a/web/app/templates/auth/register.html.j2
+++ b/web/app/templates/auth/register.html.j2
@@ -1,5 +1,5 @@
 {% extends "nopaque.html.j2" %}
-{% import 'materialize/wtf.html.j2' as wtf %}
+{% import "materialize/wtf.html.j2" as wtf %}
 
 {% block nav_content %}
 {% include 'auth/_breadcrumbs.html.j2' %}
diff --git a/web/app/templates/auth/reset_password.html.j2 b/web/app/templates/auth/reset_password.html.j2
index 4002c158..ec9c6b18 100644
--- a/web/app/templates/auth/reset_password.html.j2
+++ b/web/app/templates/auth/reset_password.html.j2
@@ -1,5 +1,5 @@
 {% extends "nopaque.html.j2" %}
-{% import 'materialize/wtf.html.j2' as wtf %}
+{% import "materialize/wtf.html.j2" as wtf %}
 
 {% block nav_content %}
 {% include 'auth/_breadcrumbs.html.j2' %}
diff --git a/web/app/templates/auth/reset_password_request.html.j2 b/web/app/templates/auth/reset_password_request.html.j2
index 07a0808e..1f65091a 100644
--- a/web/app/templates/auth/reset_password_request.html.j2
+++ b/web/app/templates/auth/reset_password_request.html.j2
@@ -1,5 +1,5 @@
 {% extends "nopaque.html.j2" %}
-{% import 'materialize/wtf.html.j2' as wtf %}
+{% import "materialize/wtf.html.j2" as wtf %}
 
 {% block nav_content %}
 {% include 'auth/_breadcrumbs.html.j2' %}
diff --git a/web/app/templates/corpora/add_corpus.html.j2 b/web/app/templates/corpora/add_corpus.html.j2
index c5e5e3b9..0785ed11 100644
--- a/web/app/templates/corpora/add_corpus.html.j2
+++ b/web/app/templates/corpora/add_corpus.html.j2
@@ -1,16 +1,12 @@
 {% extends "nopaque.html.j2" %}
-{% from '_colors.html.j2' import colors %}
-{% import 'materialize/wtf.html.j2' as wtf %}
+{% import "materialize/wtf.html.j2" as wtf %}
 
-{% set scheme_primary_color = colors.corpus_analysis_darken %}
-{% set scheme_secondary_color = colors.corpus_analysis %}
+{% block main_attribs %} class="service-scheme" data-service="corpus-analysis"{% endblock main_attribs %}
 
 {% block nav_content %}
 {% include 'corpora/_breadcrumbs.html.j2' %}
 {% endblock nav_content %}
 
-{% block main_attribs %} class="corpus-analysis-color lighten"{% endblock main_attribs %}
-
 {% block page_content %}
 <div class="container">
   <div class="row">
diff --git a/web/app/templates/corpora/add_corpus_file.html.j2 b/web/app/templates/corpora/add_corpus_file.html.j2
index 14b09304..be3e9f71 100644
--- a/web/app/templates/corpora/add_corpus_file.html.j2
+++ b/web/app/templates/corpora/add_corpus_file.html.j2
@@ -1,16 +1,12 @@
 {% extends "nopaque.html.j2" %}
-{% from '_colors.html.j2' import colors %}
-{% import 'materialize/wtf.html.j2' as wtf %}
+{% import "materialize/wtf.html.j2" as wtf %}
 
-{% set scheme_primary_color = colors.corpus_analysis_darken %}
-{% set scheme_secondary_color = colors.corpus_analysis %}
+{% block main_attribs %} class="service-scheme" data-service="corpus-analysis"{% endblock main_attribs %}
 
 {% block nav_content %}
 {% include 'corpora/_breadcrumbs.html.j2' %}
 {% endblock nav_content %}
 
-{% block main_attribs %} class="corpus-analysis-color lighten"{% endblock main_attribs %}
-
 {% block page_content %}
 <div class="container">
   <div class="row">
diff --git a/web/app/templates/corpora/analyse_corpus.html.j2 b/web/app/templates/corpora/analyse_corpus.html.j2
index d7213988..691517b5 100644
--- a/web/app/templates/corpora/analyse_corpus.html.j2
+++ b/web/app/templates/corpora/analyse_corpus.html.j2
@@ -1,16 +1,12 @@
 {% extends "nopaque.html.j2" %}
-{% from '_colors.html.j2' import colors %}
-{% import 'materialize/wtf.html.j2' as wtf %}
+{% import "materialize/wtf.html.j2" as wtf %}
 
-{% set scheme_primary_color = colors.corpus_analysis_darken %}
-{% set scheme_secondary_color = colors.corpus_analysis %}
+{% block main_attribs %} class="service-scheme" data-service="corpus-analysis"{% endblock main_attribs %}
 
 {% block nav_content %}
 {% include 'corpora/_breadcrumbs.html.j2' %}
 {% endblock nav_content %}
 
-{% block main_attribs %} class="corpus-analysis-color lighten"{% endblock main_attribs %}
-
 {% block page_content %}
 <div class="row">
   <div class="col s12">
diff --git a/web/app/templates/corpora/corpus.html.j2 b/web/app/templates/corpora/corpus.html.j2
index 96da6976..510f2091 100644
--- a/web/app/templates/corpora/corpus.html.j2
+++ b/web/app/templates/corpora/corpus.html.j2
@@ -1,9 +1,6 @@
 {% extends "nopaque.html.j2" %}
-{% from '_colors.html.j2' import colors %}
 
-{% set scheme_primary_color = colors.corpus_analysis_darken %}
-{% set scheme_secondary_color = colors.corpus_analysis_lighten %}
-{% block main_attribs %} style="background-color: {{ scheme_secondary_color }};"{% endblock main_attribs %}
+{% block main_attribs %} class="service-scheme" data-service="corpus-analysis"{% endblock main_attribs %}
 
 {% block nav_content %}
 {% include 'corpora/_breadcrumbs.html.j2' %}
@@ -37,8 +34,8 @@
         </div>
       </div>
 
-      <div class="card">
-        <div class="card-content" style="border-top: 10px solid {{ scheme_primary_color }}">
+      <div class="card service-color-border border-darken" data-service="corpus-analysis" style="border-top: 10px solid">
+        <div class="card-content">
           <div class="row">
             <div class="col s12">
               <div class="input-field">
diff --git a/web/app/templates/corpora/corpus_file.html.j2 b/web/app/templates/corpora/corpus_file.html.j2
index d8022303..e5dc31eb 100644
--- a/web/app/templates/corpora/corpus_file.html.j2
+++ b/web/app/templates/corpora/corpus_file.html.j2
@@ -1,16 +1,12 @@
 {% extends "nopaque.html.j2" %}
-{% from '_colors.html.j2' import colors %}
-{% import 'materialize/wtf.html.j2' as wtf %}
+{% import "materialize/wtf.html.j2" as wtf %}
 
-{% set scheme_primary_color = colors.corpus_analysis_darken %}
-{% set scheme_secondary_color = colors.corpus_analysis %}
+{% block main_attribs %} class="service-scheme" data-service="corpus-analysis"{% endblock main_attribs %}
 
 {% block nav_content %}
 {% include 'corpora/_breadcrumbs.html.j2' %}
 {% endblock nav_content %}
 
-{% block main_attribs %} class="corpus-analysis-color lighten"{% endblock main_attribs %}
-
 {% block page_content %}
 <div class="container">
   <div class="row">
diff --git a/web/app/templates/corpora/import_corpus.html.j2 b/web/app/templates/corpora/import_corpus.html.j2
index 1a8caf08..9531e844 100644
--- a/web/app/templates/corpora/import_corpus.html.j2
+++ b/web/app/templates/corpora/import_corpus.html.j2
@@ -1,16 +1,12 @@
-  {% extends "nopaque.html.j2" %}
-{% from '_colors.html.j2' import colors %}
-{% import 'materialize/wtf.html.j2' as wtf %}
+{% extends "nopaque.html.j2" %}
+{% import "materialize/wtf.html.j2" as wtf %}
 
-{% set scheme_primary_color = colors.corpus_analysis_darken %}
-{% set scheme_secondary_color = colors.corpus_analysis %}
+{% block main_attribs %} class="service-scheme" data-service="corpus-analysis"{% endblock main_attribs %}
 
 {% block nav_content %}
 {% include 'corpora/_breadcrumbs.html.j2' %}
 {% endblock nav_content %}
 
-{% block main_attribs %} class="corpus-analysis-color lighten"{% endblock main_attribs %}
-
 {% block page_content %}
 <div class="container">
   <div class="row">
diff --git a/web/app/templates/corpora/interactions/display.html.j2 b/web/app/templates/corpora/interactions/display.html.j2
index f6b7b490..8eb96e8e 100644
--- a/web/app/templates/corpora/interactions/display.html.j2
+++ b/web/app/templates/corpora/interactions/display.html.j2
@@ -1,4 +1,4 @@
-{% import 'materialize/wtf.html.j2' as wtf %}
+{% import "materialize/wtf.html.j2" as wtf %}
 
 <!-- HTML to allow the user to change how the results are being displayed.-->
 <div class="col s12 m3 l2" id="display">
diff --git a/web/app/templates/corpora/query_results/add_query_result.html.j2 b/web/app/templates/corpora/query_results/add_query_result.html.j2
index 6ad4ebd6..04fbb6ef 100644
--- a/web/app/templates/corpora/query_results/add_query_result.html.j2
+++ b/web/app/templates/corpora/query_results/add_query_result.html.j2
@@ -1,16 +1,12 @@
 {% extends "nopaque.html.j2" %}
-{% from '_colors.html.j2' import colors %}
-{% import 'materialize/wtf.html.j2' as wtf %}
+{% import "materialize/wtf.html.j2" as wtf %}
 
-{% set scheme_primary_color = colors.corpus_analysis_darken %}
-{% set scheme_secondary_color = colors.corpus_analysis %}
+{% block main_attribs %} class="service-scheme" data-service="corpus-analysis"{% endblock main_attribs %}
 
 {% block nav_content %}
 {% include 'corpora/query_results/_breadcrumbs.html.j2' %}
 {% endblock nav_content %}
 
-{% block main_attribs %} class="corpus-analysis-color lighten"{% endblock main_attribs %}
-
 {% block page_content %}
 <div class="container">
   <div class="row">
diff --git a/web/app/templates/corpora/query_results/inspect.html.j2 b/web/app/templates/corpora/query_results/inspect.html.j2
index 252dd974..405b6e2a 100644
--- a/web/app/templates/corpora/query_results/inspect.html.j2
+++ b/web/app/templates/corpora/query_results/inspect.html.j2
@@ -1,21 +1,16 @@
 {% extends "nopaque.html.j2" %}
-{% from '_colors.html.j2' import colors %}
 
-{% set scheme_primary_color = colors.corpus_analysis_darken %}
-{% set scheme_secondary_color = colors.corpus_analysis %}
+{% block main_attribs %} class="service-scheme" data-service="corpus-analysis"{% endblock main_attribs %}
 
 {% block nav_content %}
 {% include 'corpora/query_results/_breadcrumbs.html.j2' %}
 {% endblock nav_content %}
 
-{% block main_attribs %} class="corpus-analysis-color lighten"{% endblock main_attribs %}
-
 {% block page_content %}
 <div class="row">
   <div class="col s12">
     <div class="card">
-      <div class="card-content" style="padding-top: 5px;
-                               padding-bottom: 0px;">
+      <div class="card-content" style="padding-top: 5px; padding-bottom: 0px;">
         <!-- Query form -->
         <div class="row">
         <form id="query-form">
diff --git a/web/app/templates/corpora/query_results/query_result.html.j2 b/web/app/templates/corpora/query_results/query_result.html.j2
index 24ce8978..e3d772bb 100644
--- a/web/app/templates/corpora/query_results/query_result.html.j2
+++ b/web/app/templates/corpora/query_results/query_result.html.j2
@@ -1,15 +1,11 @@
 {% extends "nopaque.html.j2" %}
-{% from '_colors.html.j2' import colors %}
 
-{% set scheme_primary_color = colors.corpus_analysis_darken %}
-{% set scheme_secondary_color = colors.corpus_analysis %}
+{% block main_attribs %} class="service-scheme" data-service="corpus-analysis"{% endblock main_attribs %}
 
 {% block nav_content %}
 {% include 'corpora/query_results/_breadcrumbs.html.j2' %}
 {% endblock nav_content %}
 
-{% block main_attribs %} class="corpus-analysis-color lighten"{% endblock main_attribs %}
-
 {% block page_content %}
 <div class="container">
   <div class="row">
diff --git a/web/app/templates/jobs/job.html.j2 b/web/app/templates/jobs/job.html.j2
index c35e259b..51a2b8ed 100644
--- a/web/app/templates/jobs/job.html.j2
+++ b/web/app/templates/jobs/job.html.j2
@@ -1,17 +1,6 @@
 {% extends "nopaque.html.j2" %}
-{% from '_colors.html.j2' import colors %}
 
-{% if job.service == 'file-setup' %}
-  {% set scheme_primary_color = colors.file_setup_darken %}
-  {% set scheme_secondary_color = colors.file_setup_lighten %}
-{% elif job.service == 'nlp' %}
-  {% set scheme_primary_color = colors.nlp_darken %}
-  {% set scheme_secondary_color = colors.nlp_lighten %}
-{% elif job.service == 'ocr' %}
-  {% set scheme_primary_color = colors.ocr_darken %}
-  {% set scheme_secondary_color = colors.ocr_lighten %}
-{% endif %}
-{% block main_attribs %} style="background-color: {{ scheme_secondary_color }};"{% endblock main_attribs %}
+{% block main_attribs %} class="service-scheme" data-service="{{ job.service }}"{% endblock main_attribs %}
 
 {% block nav_content %}
 {% include 'jobs/_breadcrumbs.html.j2' %}
@@ -45,7 +34,7 @@
         </div>
       </div>
 
-      <div class="card" style="border-top: 10px solid {{ scheme_primary_color }}">
+      <div class="card service-color-border border-darken" data-service="{{ job.service }}" style="border-top: 10px solid">
         <div class="card-content">
           <div class="row">
             <div class="col s12">
diff --git a/web/app/templates/main/dashboard.html.j2 b/web/app/templates/main/dashboard.html.j2
index b131b015..3ae228b8 100644
--- a/web/app/templates/main/dashboard.html.j2
+++ b/web/app/templates/main/dashboard.html.j2
@@ -132,36 +132,36 @@
                 <div class="card-panel center-align hoverable">
                   <br>
                   <a href="{{ url_for('services.service', service='file-setup') }}" class="btn-floating btn-large waves-effect waves-light" style="transform: scale(2);">
-                    <i class="nopaque-icons service-color service-icon" data-service="file-setup" style="font-size: 2.5rem;"></i>
+                    <i class="nopaque-icons service-color darken service-icon" data-service="file-setup"></i>
                   </a>
                   <br><br>
-                  <p class="file-setup-color-text darken"><b>File setup</b></p>
+                  <p class="service-color-text darken" data-service="file-setup"><b>File setup</b></p>
                   <p class="light">Digital copies of text based research data (books, letters, etc.) often comprise various files and formats. nopaque converts and merges those files to facilitate further processing and the application of other services.</p>
-                  <a href="{{ url_for('services.service', service='file-setup') }}" class="waves-effect waves-light btn file-setup-color darken">Create Job</a>
+                  <a href="{{ url_for('services.service', service='file-setup') }}" class="waves-effect waves-light btn service-color darken" data-service="file-setup">Create Job</a>
                 </div>
             </div>
             <div class="col s12 m4">
                 <div class="card-panel center-align hoverable">
                   <br>
                   <a href="{{ url_for('services.service', service='ocr') }}" class="btn-floating btn-large waves-effect waves-light" style="transform: scale(2);">
-                    <i class="nopaque-icons service-color service-icon" data-service="ocr" style="font-size: 2.5rem;"></i>
+                    <i class="nopaque-icons service-color darken service-icon" data-service="ocr" style="font-size: 2.5rem;"></i>
                   </a>
                   <br><br>
-                  <p class="ocr-color-text darken"><b>Optical Character Recognition</b></p>
+                  <p class="service-color-text darken" data-service="ocr"><b>Optical Character Recognition</b></p>
                   <p class="light">nopaque converts your image data – like photos or scans – into text data through a process called OCR. This step enables you to proceed with further computational analysis of your documents.</p>
-                  <a href="{{ url_for('services.service', service='ocr') }}" class="waves-effect waves-light btn ocr-color darken">Create Job</a>
+                  <a href="{{ url_for('services.service', service='ocr') }}" class="waves-effect waves-light btn service-color darken" data-service="ocr">Create Job</a>
                 </div>
             </div>
             <div class="col s12 m4">
                 <div class="card-panel center-align hoverable">
                   <br>
                   <a href="{{ url_for('services.service', service='nlp') }}" class="btn-floating btn-large waves-effect waves-light" style="transform: scale(2);">
-                    <i class="nopaque-icons service-color service-icon" data-service="nlp" style="font-size: 2.5rem;"></i>
+                    <i class="nopaque-icons service-color darken service-icon" data-service="nlp" style="font-size: 2.5rem;"></i>
                   </a>
                   <br><br>
-                  <p class="nlp-color-text darken"><b>Natural Language Processing</b></p>
+                  <p class="service-color-text darken" data-service="nlp"><b>Natural Language Processing</b></p>
                   <p class="light">By means of computational linguistic data processing (tokenization, lemmatization, part-of-speech tagging and named-entity recognition) nopaque extracts additional information from your text.</p>
-                  <a href="{{ url_for('services.service', service='nlp') }}" class="waves-effect waves-light btn nlp-color darken">Create Job</a>
+                  <a href="{{ url_for('services.service', service='nlp') }}" class="waves-effect waves-light btn service-color darken" data-service="nlp">Create Job</a>
                 </div>
             </div>
           </div>
diff --git a/web/app/templates/main/index.html.j2 b/web/app/templates/main/index.html.j2
index a855aef8..6be76c8e 100644
--- a/web/app/templates/main/index.html.j2
+++ b/web/app/templates/main/index.html.j2
@@ -1,5 +1,5 @@
 {% extends "nopaque.html.j2" %}
-{% import 'materialize/wtf.html.j2' as wtf %}
+{% import "materialize/wtf.html.j2" as wtf %}
 
 {% block nav_content %}
 {% include 'main/_breadcrumbs.html.j2' %}
@@ -80,34 +80,34 @@
           <div class="row">
             <div class="col s12 m6 l3 center-align">
               <a href="{{ url_for('services.service', service='file-setup') }}" class="btn-floating btn-large btn-scale-x2 waves-effect waves-light">
-                <i class="nopaque-icons service-color service-icon" data-service="file-setup"></i>
+                <i class="nopaque-icons service-color darken service-icon" data-service="file-setup"></i>
               </a>
               <br><br>
-              <p class="file-setup-color-text text-darken"><b>File setup</b></p>
+              <p class="service-color-text text-darken" data-service="file-setup"><b>File setup</b></p>
               <p class="light">Digital copies of text based research data (books, letters, etc.) often comprise various files and formats. nopaque converts and merges those files to facilitate further processing and the application of other services.</p>
             </div>
             <div class="col s12 m6 l3 center-align">
               <a href="{{ url_for('services.service', service='ocr') }}" class="btn-floating btn-large btn-scale-x2 waves-effect waves-light">
-                <i class="nopaque-icons service-color service-icon" data-service="ocr"></i>
+                <i class="nopaque-icons service-color darken service-icon" data-service="ocr"></i>
               </a>
               <br><br>
-              <p class="ocr-color-text text-darken"><b>Optical Character Recognition</b></p>
+              <p class="service-color-text text-darken" data-service="ocr"><b>Optical Character Recognition</b></p>
               <p class="light">nopaque converts your image data – like photos or scans – into text data through OCR making it machine readable. This step enables you to proceed with further computational analysis of your documents.</p>
             </div>
             <div class="col s12 m6 l3 center-align">
               <a href="{{ url_for('services.service', service='nlp') }}" class="btn-floating btn-large btn-scale-x2 waves-effect waves-light">
-                <i class="nopaque-icons service-color service-icon" data-service="nlp"></i>
+                <i class="nopaque-icons service-color darken service-icon" data-service="nlp"></i>
               </a>
               <br><br>
-              <p class="nlp-color-text text-darken"><b>Natural Language Processing</b></p>
+              <p class="service-color-text text-darken" data-service="nlp"><b>Natural Language Processing</b></p>
               <p class="light">By means of computational linguistic data processing (tokenization, lemmatization, part-of-speech tagging and named-entity recognition) nopaque extracts additional information from your text.</p>
             </div>
             <div class="col s12 m6 l3 center-align">
               <a href="{{ url_for('services.service', service='corpus_analysis') }}" class="btn-floating btn-large btn-scale-x2 waves-effect waves-light">
-                <i class="nopaque-icons service-color service-icon" data-service="corpus-analysis"></i>
+                <i class="nopaque-icons service-color darken service-icon" data-service="corpus-analysis"></i>
               </a>
               <br><br>
-              <p class="corpus-analysis-color-text text-darken"><b>Corpus analysis</b></p>
+              <p class="service-color-text text-darken" data-service="corpus-analysis"><b>Corpus analysis</b></p>
               <p class="light">nopaque lets you create and upload as many text corpora as you want. It makes use of CQP Query Language, which allows for complex search requests with the aid of metadata and NLP tags.</p>
             </div>
           </div>
diff --git a/web/app/templates/nopaque.html.j2 b/web/app/templates/nopaque.html.j2
index 49e182b7..dba9022e 100644
--- a/web/app/templates/nopaque.html.j2
+++ b/web/app/templates/nopaque.html.j2
@@ -1,5 +1,4 @@
 {% extends "materialize/base.html.j2" %}
-{% from '_colors.html.j2' import colors %}
 
 {% block html_attribs %} lang="en"{% endblock html_attribs %}
 
@@ -18,71 +17,11 @@
 {% block styles %}
 {{ super() }}
 {% if current_user.is_authenticated %}
-<link href="{{ url_for('static', filename='css/materialize.sidenav-fixed.css') }}" media="screen,projection" rel="stylesheet">
+<link href="{{ url_for('static', filename='css/sidenav_fixed.css') }}" media="screen,projection" rel="stylesheet">
 {% endif %}
-<link href="{{ url_for('static', filename='css/materialize.sticky-footer.css') }}" media="screen,projection" rel="stylesheet">
 <link href="{{ url_for('static', filename='css/nopaque_icons.css') }}" media="screen,projection" rel="stylesheet">
 <link href="{{ url_for('static', filename='css/nopaque.css') }}" media="screen,projection" rel="stylesheet">
-<style>
-  .primary-color {background-color: {{ colors.primary }} !important;}
-  .primary-color-text {color: {{ colors.primary }} !important;}
-  .secondary-color {background-color: {{ colors.secondary }} !important;}
-  .secondary-color-text {color: {{ colors.secondary }} !important;}
-  .footer-color {background-color: {{ colors.footer }} !important;}
-  .footer-color-text {color: {{ colors.footer }} !important;}
-
-  .corpus-analysis-color {background-color: {{ colors.corpus_analysis }} !important;}
-  .corpus-analysis-color-text {color: {{ colors.corpus_analysis }} !important;}
-  .corpus-analysis-color.darken {background-color: {{ colors.corpus_analysis_darken }} !important;}
-  .corpus-analysis-color-text.text-darken {color: {{ colors.corpus_analysis_darken }} !important;}
-  .corpus-analysis-color.lighten {background-color: {{ colors.corpus_analysis_lighten }} !important;}
-  .corpus-analysis-color-text.text-lighten {color: {{ colors.corpus_analysis_lighten }} !important;}
-  .service-color[data-service="corpus-analysis"] {background-color: {{ colors.corpus_analysis_darken }} !important;}
-
-  .file-setup-color {background-color: {{ colors.file_setup }} !important;}
-  .file-setup-color-text {color: {{ colors.file_setup }} !important;}
-  .file-setup-color.darken {background-color: {{ colors.file_setup_darken }} !important;}
-  .file-setup-color-text.text-darken {color: {{ colors.file_setup_darken }} !important;}
-  .file-setup-color.lighten {background-color: {{ colors.file_setup_lighten }} !important;}
-  .file-setup-color-text.text-lighten {color: {{ colors.file_setup_lighten }} !important;}
-  .service-color[data-service="file-setup"] {background-color: {{ colors.file_setup_darken }} !important;}
-
-  .ocr-color {background-color: {{ colors.ocr }} !important;}
-  .ocr-color-text {color: {{ colors.ocr }} !important;}
-  .ocr-color.darken {background-color: {{ colors.ocr_darken }} !important;}
-  .ocr-color-text.text-darken {color: {{ colors.ocr_darken }} !important;}
-  .ocr-color.lighten {background-color: {{ colors.ocr_lighten }} !important;}
-  .ocr-color-text.text-lighten {color: {{ colors.ocr_lighten }} !important;}
-  .service-color[data-service="ocr"] {background-color: {{ colors.ocr_darken }} !important;}
-
-  .nlp-color {background-color: {{ colors.nlp }} !important;}
-  .nlp-color-text {color: {{ colors.nlp }} !important;}
-  .nlp-color.darken {background-color: {{ colors.nlp_darken }} !important;}
-  .nlp-color-text.text-darken {color: {{ colors.nlp_darken }} !important;}
-  .nlp-color.lighten {background-color: {{ colors.nlp_lighten }} !important;}
-  .nlp-color-text.text-lighten {color: {{ colors.nlp_lighten }} !important;}
-  .service-color[data-service="nlp"] {background-color: {{ colors.nlp_darken }} !important;}
-
-  {% if scheme_primary_color is not defined %}
-    {% set scheme_primary_color = colors.primary %}
-  {% endif %}
-  {% if scheme_secondary_color is not defined %}
-    {% set scheme_secondary_color = colors.secondary %}
-  {% endif %}
-  main .btn, main .btn-small, main .btn-large, main .btn-floating {background-color: {{ scheme_primary_color }};}
-  main .btn:hover, main .btn-large:hover, main .btn-small:hover, main .btn-floating:hover {background-color: {{ scheme_secondary_color }};}
-  main .pagination li.active {background-color: {{ scheme_primary_color }};}
-  main .table-of-contents a.active {border-color: {{ scheme_primary_color }};}
-  main .tabs .tab a {color: inherit;}
-  main .tabs .tab.disabled a {color: {{ scheme_primary_color }}28;}
-  main .tabs .tab.disabled a:hover {color: {{ scheme_primary_color }}28;}
-  main .tabs .tab a:hover {color: {{ scheme_primary_color }};}
-  main .tabs .tab a.active, .tabs .tab a:focus.active {
-    color: {{ scheme_primary_color }};
-    background-color: {{ scheme_primary_color }}28;
-  }
-  main .tabs .indicator {background-color: {{ scheme_primary_color }};}
-</style>
+{% include "_color.html.j2" %}
 {% endblock styles %}
 
 {% block navbar %}
@@ -100,7 +39,7 @@
         <li><a class="dropdown-trigger no-autoinit" data-target="nav-more-dropdown" href="#!" id="nav-more-dropdown-trigger"><i class="material-icons">more_vert</i></a></li>
       </ul>
     </div>
-    <div class="nav-content secondary-color">
+    <div class="nav-content primary-variant-color">
       {% block nav_content %}{% endblock nav_content %}
       {% if current_user.is_authenticated %}
       <a class="btn-floating btn-large halfway-fab modal-trigger pink tooltipped waves-effect waves-light" data-tooltip="Roadmap" href="#roadmap-modal"><i class="material-icons">explore</i></a>
@@ -122,8 +61,8 @@
 {% endblock navbar %}
 
 {% block sidenav %}
-<ul class="sidenav sidenav-fixed{% if not current_user.is_authenticated %} hide{% endif %}" id="sidenav">
-  {% if current_user.is_authenticated %}
+{% if current_user.is_authenticated %}
+<ul class="sidenav sidenav-fixed" id="sidenav">
   <li>
     <div class="user-view">
       <div class="background primary-color"></div>
@@ -139,28 +78,23 @@
   <li><a href="{{ url_for('main.dashboard', _anchor='jobs') }}" style="padding-left: 47px;"><i class="nopaque-icons">J</i>My Jobs</a></li>
   <li><div class="divider"></div></li>
   <li><a class="subheader">Processes & Services</a></li>
-  <li style="background-color: {{ colors.file_setup }}; border-left: 10px solid {{ colors.file_setup_darken }};"><a href="{{ url_for('services.service', service='file-setup') }}"><i class="nopaque-icons service-icon" data-service="file-setup"></i>File setup</a></li>
-  <li style="background-color: {{ colors.ocr }}; border-left: 10px solid {{ colors.ocr_darken }}; margin-top: 5px;"><a href="{{ url_for('services.service', service='ocr') }}"><i class="nopaque-icons service-icon" data-service="ocr"></i>OCR</a></li>
-  <li style="background-color: {{ colors.nlp }}; border-left: 10px solid {{ colors.nlp_darken }}; margin-top: 5px;"><a href="{{ url_for('services.service', service='nlp') }}"><i class="nopaque-icons service-icon" data-service="nlp"></i>NLP</a></li>
-  <li style="background-color: {{ colors.corpus_analysis }}; border-left: 10px solid {{ colors.corpus_analysis_darken }}; margin-top: 5px;"><a href="{{ url_for('services.service', service='corpus_analysis') }}"><i class="nopaque-icons service-icon" data-service="corpus-analysis"></i>Corpus analysis</a></li>
+  <li class="service-color service-color-border border-darken" data-service="file-setup" style="border-left: 10px solid; margin-top: 5px;"><a href="{{ url_for('services.service', service='file_setup') }}"><i class="nopaque-icons service-icon" data-service="file-setup"></i>File setup</a></li>
+  <li class="service-color service-color-border border-darken" data-service="ocr" style="border-left: 10px solid; margin-top: 5px;"><a href="{{ url_for('services.service', service='ocr') }}"><i class="nopaque-icons service-icon" data-service="ocr"></i>OCR</a></li>
+  <li class="service-color service-color-border border-darken" data-service="nlp" style="border-left: 10px solid; margin-top: 5px;"><a href="{{ url_for('services.service', service='nlp') }}"><i class="nopaque-icons service-icon" data-service="nlp"></i>NLP</a></li>
+  <li class="service-color service-color-border border-darken" data-service="corpus-analysis" style="border-left: 10px solid; margin-top: 5px;"><a href="{{ url_for('services.service', service='corpus_analysis') }}"><i class="nopaque-icons service-icon" data-service="corpus-analysis"></i>Corpus analysis</a></li>
   <li><div class="divider"></div></li>
   <li><a class="subheader">Account</a></li>
   <li><a href="{{ url_for('settings.index') }}"><i class="material-icons">settings</i>Settings</a></li>
   <li><a href="{{ url_for('auth.logout') }}">Log out</a></li>
-  {% else %}
-  <li><a href="{{ url_for('auth.register') }}"><i class="material-icons">assignment</i>Register</a></li>
-  <li><a href="{{ url_for('auth.login') }}"><i class="material-icons">login</i>Log in</a></li>
-  {% endif %}
   {% if current_user.is_administrator() %}
   <li><div class="divider"></div></li>
   <li><a class="subheader">Administration</a></li>
   <li><a href="{{ url_for('admin.index') }}"><i class="material-icons">build</i>Administration</a></li>
   {% endif %}
 </ul>
+{% endif %}
 {% endblock sidenav %}
 
-{% block main_attribs %} class="grey lighten-5"{% endblock main_attribs %}
-
 {% block main %}
 {% block page_content %}{% endblock page_content %}
 {% if current_user.is_authenticated %}
@@ -201,7 +135,7 @@
 {% endif %}
 {% endblock main %}
 
-{% block footer_attribs %} class="page-footer footer-color"{% endblock footer_attribs %}
+{% block footer_attribs %} class="page-footer primary-variant-color"{% endblock footer_attribs %}
 
 {% block footer %}
 <div class="container">
@@ -258,13 +192,13 @@
 <script src="{{ url_for('static', filename='js/list.min.js') }}"></script>
 <script src="{{ url_for('static', filename='js/socket.io.min.js') }}"></script>
 <script src="{{ url_for('static', filename='js/nopaque/main.js') }}"></script>
-{% assets output="js/nopaque/RessourceDisplays.compiled.js",
+{% assets filters='rjsmin', output="js/nopaque/RessourceDisplays.min.compiled.js",
           "js/nopaque/RessourceDisplays/RessourceDisplay.js",
           "js/nopaque/RessourceDisplays/CorpusDisplay.js",
           "js/nopaque/RessourceDisplays/JobDisplay.js" %}
 <script src="{{ ASSET_URL }}"></script>
 {% endassets %}
-{% assets output="js/nopaque/RessourceLists.compiled.js",
+{% assets filters='rjsmin', output="js/nopaque/RessourceLists.min.compiled.js",
           "js/nopaque/RessourceLists/RessourceList.js",
           "js/nopaque/RessourceLists/CorpusList.js",
           "js/nopaque/RessourceLists/CorpusFileList.js",
diff --git a/web/app/templates/services/corpus_analysis.html.j2 b/web/app/templates/services/corpus_analysis.html.j2
index 8e2050d8..9e83a71f 100644
--- a/web/app/templates/services/corpus_analysis.html.j2
+++ b/web/app/templates/services/corpus_analysis.html.j2
@@ -1,15 +1,11 @@
 {% extends "nopaque.html.j2" %}
-{% from '_colors.html.j2' import colors %}
 
-{% set scheme_primary_color = colors.corpus_analysis_darken %}
-{% set scheme_secondary_color = colors.corpus_analysis %}
+{% block main_attribs %} class="service-scheme" data-service="corpus-analysis"{% endblock main_attribs %}
 
 {% block nav_content %}
 {% include 'services/_breadcrumbs.html.j2' %}
 {% endblock nav_content %}
 
-{% block main_attribs %} class="corpus-analysis-color lighten"{% endblock main_attribs %}
-
 {% block page_content %}
 <div class="container">
   <div class="row">
@@ -20,7 +16,7 @@
     <div class="col s12 m3 push-m9">
       <div class="center-align">
         <a class="btn-floating btn-large btn-scale-x2 waves-effect waves-light" style="transform: scale(2);">
-          <i class="nopaque-icons service-color service-icon" data-service="corpus-analysis"></i>
+          <i class="nopaque-icons service-color darken service-icon" data-service="corpus-analysis"></i>
         </a>
       </div>
     </div>
diff --git a/web/app/templates/services/file-setup.html.j2 b/web/app/templates/services/file_setup.html.j2
similarity index 85%
rename from web/app/templates/services/file-setup.html.j2
rename to web/app/templates/services/file_setup.html.j2
index 98e3591e..d6627861 100644
--- a/web/app/templates/services/file-setup.html.j2
+++ b/web/app/templates/services/file_setup.html.j2
@@ -1,16 +1,12 @@
 {% extends "nopaque.html.j2" %}
-{% import 'materialize/wtf.html.j2' as wtf %}
-{% from '_colors.html.j2' import colors %}
+{% import "materialize/wtf.html.j2" as wtf %}
 
-{% set scheme_primary_color = colors.file_setup_darken %}
-{% set scheme_secondary_color = colors.file_setup %}
+{% block main_attribs %} class="service-scheme" data-service="file-setup"{% endblock main_attribs %}
 
 {% block nav_content %}
 {% include 'services/_breadcrumbs.html.j2' %}
 {% endblock nav_content %}
 
-{% block main_attribs %} class="file-setup-color lighten"{% endblock main_attribs %}
-
 {% block page_content %}
 <div class="container">
   <div class="row">
@@ -23,13 +19,13 @@
         <p class="hide-on-small-only">&nbsp;</p>
         <p class="hide-on-small-only">&nbsp;</p>
         <a class="btn-floating btn-large btn-scale-x2 waves-effect waves-light">
-          <i class="nopaque-icons service-color service-icon" data-service="file-setup"></i>
+          <i class="nopaque-icons service-color darken service-icon" data-service="file-setup"></i>
         </a>
       </div>
     </div>
 
     <div class="col s12 m9 pull-m3">
-      <div class="card" style="border-top: 10px solid {{ colors.file_setup_darken }};">
+      <div class="card service-color-border border-darken" data-service="file-setup" style="border-top: 10px solid;">
         <div class="card-content">
           <div class="row">
             <div class="col s12">
diff --git a/web/app/templates/services/nlp.html.j2 b/web/app/templates/services/nlp.html.j2
index b8f866d5..64d6269f 100644
--- a/web/app/templates/services/nlp.html.j2
+++ b/web/app/templates/services/nlp.html.j2
@@ -1,16 +1,12 @@
 {% extends "nopaque.html.j2" %}
-{% import 'materialize/wtf.html.j2' as wtf %}
-{% from '_colors.html.j2' import colors %}
+{% import "materialize/wtf.html.j2" as wtf %}
 
-{% set scheme_primary_color = colors.nlp_darken %}
-{% set scheme_secondary_color = colors.nlp %}
+{% block main_attribs %} class="service-scheme" data-service="nlp"{% endblock main_attribs %}
 
 {% block nav_content %}
 {% include 'services/_breadcrumbs.html.j2' %}
 {% endblock nav_content %}
 
-{% block main_attribs %} class="nlp-color lighten"{% endblock main_attribs %}
-
 {% block page_content %}
 <div class="container">
   <div class="row">
@@ -23,13 +19,13 @@
         <p class="hide-on-small-only">&nbsp;</p>
         <p class="hide-on-small-only">&nbsp;</p>
         <a class="btn-floating btn-large btn-scale-x2 waves-effect waves-light">
-          <i class="nopaque-icons service-color service-icon" data-service="nlp"></i>
+          <i class="nopaque-icons service-color darken service-icon" data-service="nlp"></i>
         </a>
       </div>
     </div>
 
     <div class="col s12 m9 pull-m3">
-      <div class="card" style="border-top: 10px solid {{ colors.nlp_darken }};">
+      <div class="card service-color-border border-darken" data-service="nlp" style="border-top: 10px solid;">
         <div class="card-content">
           <div class="row">
             <div class="col s12 m6">
diff --git a/web/app/templates/services/ocr.html.j2 b/web/app/templates/services/ocr.html.j2
index 7de66928..4b641c09 100644
--- a/web/app/templates/services/ocr.html.j2
+++ b/web/app/templates/services/ocr.html.j2
@@ -1,16 +1,12 @@
 {% extends "nopaque.html.j2" %}
-{% import 'materialize/wtf.html.j2' as wtf %}
-{% from '_colors.html.j2' import colors %}
+{% import "materialize/wtf.html.j2" as wtf %}
 
-{% set scheme_primary_color = colors.ocr_darken %}
-{% set scheme_secondary_color = colors.ocr %}
+{% block main_attribs %} class="service-scheme" data-service="ocr"{% endblock main_attribs %}
 
 {% block nav_content %}
 {% include 'services/_breadcrumbs.html.j2' %}
 {% endblock nav_content %}
 
-{% block main_attribs %} class="ocr-color lighten"{% endblock main_attribs %}
-
 {% block page_content %}
 <div class="container">
   <div class="row">
@@ -23,13 +19,13 @@
         <p class="hide-on-small-only">&nbsp;</p>
         <p class="hide-on-small-only">&nbsp;</p>
         <a class="btn-floating btn-large btn-scale-x2 waves-effect waves-light">
-          <i class="nopaque-icons service-color service-icon" data-service="ocr"></i>
+          <i class="nopaque-icons service-color darken service-icon" data-service="ocr"></i>
         </a>
       </div>
     </div>
 
     <div class="col s12 m9 pull-m3">
-      <div class="card" style="border-top: 10px solid {{ colors.ocr_darken }};">
+      <div class="card service-color-border border-darken" data-service="ocr" style="border-top: 10px solid;">
         <div class="card-content">
           <div class="row">
             <div class="col s12">
diff --git a/web/app/templates/settings/change_password.html.j2 b/web/app/templates/settings/change_password.html.j2
index f1714dc5..c4f76cbd 100644
--- a/web/app/templates/settings/change_password.html.j2
+++ b/web/app/templates/settings/change_password.html.j2
@@ -1,5 +1,5 @@
 {% extends 'nopaque.html.j2' %}
-{% import 'materialize/wtf.html.j2' as wtf %}
+{% import "materialize/wtf.html.j2" as wtf %}
 
 {% block nav_content %}
 {% include 'settings/_breadcrumbs.html.j2' %}
diff --git a/web/app/templates/settings/edit_general_settings.html.j2 b/web/app/templates/settings/edit_general_settings.html.j2
index 286983f0..f0e7953d 100644
--- a/web/app/templates/settings/edit_general_settings.html.j2
+++ b/web/app/templates/settings/edit_general_settings.html.j2
@@ -1,5 +1,5 @@
 {% extends 'nopaque.html.j2' %}
-{% import 'materialize/wtf.html.j2' as wtf %}
+{% import "materialize/wtf.html.j2" as wtf %}
 
 {% block nav_content %}
 {% include 'settings/_breadcrumbs.html.j2' %}
diff --git a/web/app/templates/settings/edit_notification_settings.html.j2 b/web/app/templates/settings/edit_notification_settings.html.j2
index e6fc7428..64a695c3 100644
--- a/web/app/templates/settings/edit_notification_settings.html.j2
+++ b/web/app/templates/settings/edit_notification_settings.html.j2
@@ -1,5 +1,5 @@
 {% extends 'nopaque.html.j2' %}
-{% import 'materialize/wtf.html.j2' as wtf %}
+{% import "materialize/wtf.html.j2" as wtf %}
 
 {% block nav_content %}
 {% include 'settings/_breadcrumbs.html.j2' %}
-- 
GitLab