]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mgr/dashboard: New Landing Page: Milestone 2
authoralfonsomthd <almartin@redhat.com>
Thu, 27 Sep 2018 07:59:50 +0000 (09:59 +0200)
committeralfonsomthd <almartin@redhat.com>
Wed, 3 Oct 2018 12:24:31 +0000 (14:24 +0200)
Changed background color to gray.

Changed cards' background color to white.

Changed card font size to fluid: from 12px to 21px.

Info Group Title: fixed font size 21px, removed underline..

CSS Flexbox layout for  perf. and capacity cards.

CSS adjustments, refactor and cleanup.

Fixes: https://tracker.ceph.com/issues/27050
Signed-off-by: Alfonso Martínez <almartin@redhat.com>
src/pybind/mgr/dashboard/frontend/src/app/app.component.html
src/pybind/mgr/dashboard/frontend/src/app/app.component.scss
src/pybind/mgr/dashboard/frontend/src/app/app.component.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/health/health.component.html
src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/health/health.component.scss
src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/info-card/info-card.component.scss
src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/info-group/info-group.component.html
src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/info-group/info-group.component.scss
src/pybind/mgr/dashboard/frontend/src/app/shared/components/select-badges/select-badges.component.scss
src/pybind/mgr/dashboard/frontend/src/defaults.scss

index 669222afc80e7394af25cb7dee0a3f75214b4016..f21c571da6370f7394bccc7cc48f5345c8db2f86 100644 (file)
@@ -1,6 +1,6 @@
 <cd-navigation *ngIf="!isLoginActive()"></cd-navigation>
 <div class="container-fluid"
-     [ngClass]="{'full-height':isLoginActive()}">
+     [ngClass]="{'full-height':isLoginActive(), 'dashboard':isDashboardPage()} ">
   <cd-breadcrumbs></cd-breadcrumbs>
   <router-outlet></router-outlet>
 </div>
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..3c6ef116106c32f3e51382e1265ad09471ea421d 100644 (file)
@@ -0,0 +1,7 @@
+@import '../defaults';
+
+.dashboard {
+  background-color: $color-whitesmoke-gray;
+  margin: 0;
+  padding: 0;
+}
index 9f5024eb621588b5ade9c2959cc788482104c371..29c168415e81fbec2df06b8e18abe3652a1f258a 100644 (file)
@@ -25,4 +25,8 @@ export class AppComponent {
   isLoginActive() {
     return this.router.url === '/login' || !this.authStorageService.isLoggedIn();
   }
+
+  isDashboardPage() {
+    return this.router.url === '/dashboard';
+  }
 }
index 05722e133f0aea1d16d392da81fd3c01924840dc..a266dffd009898f08fdb80d490419c19a908aa74 100644 (file)
@@ -45,9 +45,9 @@
                   i18n-cardTitle
                   link="/osd"
                   class="col-sm-6 col-md-4 col-lg-3"
-                  *ngIf="(contentData.osd_map | osdSummary) as osdSummaryContent"
-                  [contentClass]="osdSummaryContent.length > 3 ? 'content-row3 content-highlight' : 'content-row2 content-highlight'">
-      <span *ngFor="let result of osdSummaryContent" [ngClass]="result.class">
+                  *ngIf="contentData.osd_map"
+                  contentClass="content-row2 content-highlight">
+      <span *ngFor="let result of (contentData.osd_map | osdSummary)" [ngClass]="result.class">
         {{ result.content }}
       </span>
     </cd-info-card>
   <cd-info-group groupTitle="Performance"
                  i18n-groupTitle
                  class="row info-group">
+    <div class="cd-container-flex">
+      <cd-info-card cardTitle="Client IOPS"
+                    i18n-cardTitle
+                    class="cd-col-5"
+                    cardClass="card-medium"
+                    contentClass="content-medium content-highlight"
+                    *ngIf="contentData.client_perf">
+        {{ (contentData.client_perf.read_op_per_sec + contentData.client_perf.write_op_per_sec) | round:1 }}
+      </cd-info-card>
 
-    <cd-info-card cardTitle="Client IOPS"
-                  i18n-cardTitle
-                  class="cd-col-5"
-                  cardClass="card-medium"
-                  contentClass="content-medium content-highlight"
-                  *ngIf="contentData.client_perf">
-      {{ (contentData.client_perf.read_op_per_sec + contentData.client_perf.write_op_per_sec) | round:1 }}
-    </cd-info-card>
+      <cd-info-card cardTitle="Client Throughput"
+                    i18n-cardTitle
+                    class="cd-col-5"
+                    cardClass="card-medium"
+                    contentClass="content-medium content-highlight"
+                    *ngIf="contentData.client_perf">
+        {{ ((contentData.client_perf.read_bytes_sec + contentData.client_perf.write_bytes_sec) | dimlessBinary) + '/s' }}
+      </cd-info-card>
 
-    <cd-info-card cardTitle="Client Throughput"
-                  i18n-cardTitle
-                  class="cd-col-5"
-                  cardClass="card-medium"
-                  contentClass="content-medium content-highlight"
-                  *ngIf="contentData.client_perf">
-      {{ ((contentData.client_perf.read_bytes_sec + contentData.client_perf.write_bytes_sec) | dimlessBinary) + '/s' }}
-    </cd-info-card>
+      <cd-info-card cardTitle="Client Read/Write"
+                    i18n-cardTitle
+                    class="cd-col-5"
+                    cardClass="card-medium"
+                    [contentClass]="(contentData.client_perf.read_op_per_sec + contentData.client_perf.write_op_per_sec) <= 0 ? 'content-medium content-highlight' : 'card-chart'"
+                    *ngIf="contentData.client_perf">
+        <cd-health-pie *ngIf="(contentData.client_perf.read_op_per_sec + contentData.client_perf.write_op_per_sec) > 0"
+                       [data]="contentData"
+                       [isBytesData]="false"
+                       chartType="pie"
+                       [displayLegend]="true"
+                       (prepareFn)="prepareReadWriteRatio($event[0], $event[1])">
+        </cd-health-pie>
+        <span *ngIf="(contentData.client_perf.read_op_per_sec + contentData.client_perf.write_op_per_sec) <= 0">
+          N/A
+        </span>
+      </cd-info-card>
 
-    <cd-info-card cardTitle="Client Read/Write"
-                  i18n-cardTitle
-                  class="cd-col-5"
-                  cardClass="card-medium"
-                  [contentClass]="(contentData.client_perf.read_op_per_sec + contentData.client_perf.write_op_per_sec) <= 0 ? 'content-medium content-highlight' : 'card-chart'"
-                  *ngIf="contentData.client_perf">
-      <cd-health-pie *ngIf="(contentData.client_perf.read_op_per_sec + contentData.client_perf.write_op_per_sec) > 0"
-                     [data]="contentData"
-                     [isBytesData]="false"
-                     chartType="pie"
-                     [displayLegend]="true"
-                     (prepareFn)="prepareReadWriteRatio($event[0], $event[1])">
-      </cd-health-pie>
-      <span *ngIf="(contentData.client_perf.read_op_per_sec + contentData.client_perf.write_op_per_sec) <= 0">
-        N/A
-      </span>
-    </cd-info-card>
+      <cd-info-card cardTitle="Client Recovery"
+                    i18n-cardTitle
+                    class="cd-col-5"
+                    cardClass="card-medium"
+                    contentClass="content-medium content-highlight"
+                    *ngIf="contentData.client_perf">
+        {{ (contentData.client_perf.recovering_bytes_per_sec | dimlessBinary) + '/s' }}
+      </cd-info-card>
 
-    <cd-info-card cardTitle="Client Recovery"
-                  i18n-cardTitle
-                  class="cd-col-5"
-                  cardClass="card-medium"
-                  contentClass="content-medium content-highlight"
-                  *ngIf="contentData.client_perf">
-      {{ (contentData.client_perf.recovering_bytes_per_sec | dimlessBinary) + '/s' }}
-    </cd-info-card>
-
-    <cd-info-card cardTitle="Scrub"
-                  i18n-cardTitle
-                  class="cd-col-5"
-                  cardClass="card-medium"
-                  contentClass="content-medium content-highlight"
-                  *ngIf="contentData.scrub_status">
-      {{ contentData.scrub_status }}
-    </cd-info-card>
+      <cd-info-card cardTitle="Scrub"
+                    i18n-cardTitle
+                    class="cd-col-5"
+                    cardClass="card-medium"
+                    contentClass="content-medium content-highlight"
+                    *ngIf="contentData.scrub_status">
+        {{ contentData.scrub_status }}
+      </cd-info-card>
+    </div>
   </cd-info-group>
 
   <cd-info-group groupTitle="Capacity"
                  i18n-groupTitle
                  class="row info-group">
 
-    <cd-info-card cardTitle="Pools"
-                  i18n-cardTitle
-                  link="/pool"
-                  class="cd-col-5"
-                  cardClass="card-medium"
-                  contentClass="content-medium content-highlight"
-                  *ngIf="contentData.pools">
-      {{ contentData.pools.length }}
-    </cd-info-card>
+    <div class="cd-container-flex">
+      <cd-info-card cardTitle="Pools"
+                    i18n-cardTitle
+                    link="/pool"
+                    class="cd-col-5"
+                    cardClass="card-medium"
+                    contentClass="content-medium content-highlight"
+                    *ngIf="contentData.pools">
+        {{ contentData.pools.length }}
+      </cd-info-card>
 
-    <cd-info-card cardTitle="Raw Capacity"
-                  i18n-cardTitle
-                  class="cd-col-5"
-                  cardClass="card-medium"
-                  contentClass="card-chart"
-                  *ngIf="contentData.mon_status">
-      <cd-health-pie [data]="contentData"
-                     [isBytesData]="true"
-                     [displayLegend]="true"
-                     (prepareFn)="prepareRawUsage($event[0], $event[1])">
-      </cd-health-pie>
-    </cd-info-card>
+      <cd-info-card cardTitle="Raw Capacity"
+                    i18n-cardTitle
+                    class="cd-col-5"
+                    cardClass="card-medium"
+                    contentClass="card-chart"
+                    *ngIf="contentData.mon_status">
+        <cd-health-pie [data]="contentData"
+                       [isBytesData]="true"
+                       [displayLegend]="true"
+                       (prepareFn)="prepareRawUsage($event[0], $event[1])">
+        </cd-health-pie>
+      </cd-info-card>
 
-    <cd-info-card cardTitle="Objects"
-                  i18n-cardTitle
-                  class="cd-col-5"
-                  cardClass="card-medium"
-                  contentClass="content-medium content-highlight"
-                  *ngIf="contentData.df?.stats?.total_objects">
-      {{ contentData.df?.stats?.total_objects }}
-    </cd-info-card>
+      <cd-info-card cardTitle="Objects"
+                    i18n-cardTitle
+                    class="cd-col-5"
+                    cardClass="card-medium"
+                    contentClass="content-medium content-highlight"
+                    *ngIf="contentData.df?.stats?.total_objects">
+        {{ contentData.df?.stats?.total_objects }}
+      </cd-info-card>
 
-    <cd-info-card cardTitle="PGs per OSD"
-                  i18n-cardTitle
-                  class="cd-col-5"
-                  cardClass="card-medium"
-                  contentClass="content-medium content-highlight"
-                  *ngIf="contentData.pg_info">
-      {{ contentData.pg_info.pgs_per_osd | dimless }}
-    </cd-info-card>
+      <cd-info-card cardTitle="PGs per OSD"
+                    i18n-cardTitle
+                    class="cd-col-5"
+                    cardClass="card-medium"
+                    contentClass="content-medium content-highlight"
+                    *ngIf="contentData.pg_info">
+        {{ contentData.pg_info.pgs_per_osd | dimless }}
+      </cd-info-card>
 
-    <cd-info-card cardTitle="PG Status"
-                  i18n-cardTitle
-                  class="cd-col-5"
-                  cardClass="card-medium"
-                  contentClass="card-chart"
-                  (click)="pgStatusTarget.toggle()">
-      <ng-template #pgStatus>
-        <p class="logs-link"
-           i18n>
-          &rarr; See <a (click)="viewportScroller.scrollToAnchor('logs')">Logs</a> for more details.
-        </p>
-        <ul>
-          <li *ngFor="let pgStatesText of contentData.pg_info.statuses | keyvalue">
-            {{ pgStatesText.key }}: {{ pgStatesText.value }}
-          </li>
-        </ul>
-      </ng-template>
-      <div class="pg-status-popover-wrapper">
-        <div [popover]="pgStatus"
-             triggers=""
-             #pgStatusTarget="bs-popover"
-             placement="bottom">
-          <cd-health-pie [data]="contentData"
-                         chartType="pie"
-                         [displayLegend]="true"
-                         (prepareFn)="preparePgStatus($event[0], $event[1])">
-          </cd-health-pie>
+      <cd-info-card cardTitle="PG Status"
+                    i18n-cardTitle
+                    class="cd-col-5"
+                    cardClass="card-medium"
+                    contentClass="card-chart"
+                    (click)="pgStatusTarget.toggle()">
+        <ng-template #pgStatus>
+          <p class="logs-link"
+             i18n>
+            &rarr; See <a (click)="viewportScroller.scrollToAnchor('logs')">Logs</a> for more details.
+          </p>
+          <ul>
+            <li *ngFor="let pgStatesText of contentData.pg_info.statuses | keyvalue">
+              {{ pgStatesText.key }}: {{ pgStatesText.value }}
+            </li>
+          </ul>
+        </ng-template>
+        <div class="pg-status-popover-wrapper">
+          <div [popover]="pgStatus"
+               triggers=""
+               #pgStatusTarget="bs-popover"
+               placement="bottom">
+            <cd-health-pie [data]="contentData"
+                           chartType="pie"
+                           [displayLegend]="true"
+                           (prepareFn)="preparePgStatus($event[0], $event[1])">
+            </cd-health-pie>
+          </div>
         </div>
-      </div>
-    </cd-info-card>
+      </cd-info-card>
+    </div>
   </cd-info-group>
 
   <cd-info-group groupTitle="Logs"
index ebcc1852c5ff6f287706b5f8634724a089fa1f79..d28d5689ba49761eed09e8ded6430201c1a1c543 100644 (file)
@@ -2,37 +2,36 @@
 
 $popover-text-font-size: 10px;
 
+.cd-container-flex {
+  margin: 0;
+  padding: 0;
+  display: -webkit-box;
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+  flex-flow: row wrap;
+  justify-content: space-between;
+}
+
 .cd-col-5 {
-  width: 17%;
-  float: left;
-  margin-left: 1.75%;
-  margin-right: 1.15%;
+  width: 20%;
 }
 
 @media (max-width: 1599px) {
   .cd-col-5 {
-    width: 30%;
-    float: left;
-    margin-left: 2.5%;
-    margin-right: 0;
+    width: 33%;
   }
 }
 
 @media (max-width: 991px) {
   .cd-col-5 {
-    width: 45%;
-    float: left;
-    margin-left: 3%;
-    margin-right: 0;
+    width: 50%;
   }
 }
 
 @media (max-width: 767px) {
   .cd-col-5 {
     width: 100%;
-    float: unset;
-    margin-left: unset;
-    margin-right: unset;
   }
 }
 
@@ -40,6 +39,10 @@ $popover-text-font-size: 10px;
   margin-bottom: 20px;
 }
 
+cd-info-card {
+  padding: 0 0.5vw 0 0.5vw;
+}
+
 ::ng-deep .health-popover-wrapper {
   position: relative;
 
index 541f3ff760180be9ac242cc8f4148e3c21d621a4..b03091f038cac32f89146e97db4e5a880cd3383d 100644 (file)
@@ -2,12 +2,16 @@
 
 $card-height: 8vw;
 $card-medium-height: 13vw;
-$logs-text-font-size: 10px;
+$card-font-min-width: 320px;
+$card-font-max-width: 1920px;
+$card-font-min-size: 12px;
+$card-font-max-size: 21px;
+$logs-text-font-size: $card-font-min-size;
 
 .card {
   border: 0.5px solid $color-info-card-border;
   border-radius: 3px;
-  background: $color-info-card-background;
+  background-color: $color-solid-white;
   box-shadow: 0 1px 1px rgba(3, 3, 3, 0.175);
   margin: 0 -10px 20px;
   padding: 0 20px;
@@ -15,19 +19,41 @@ $logs-text-font-size: 10px;
   height: auto;
   margin-left: auto;
   margin-right: auto;
-
   min-height: $card-height;
+  @include fluid-font-size(
+    $card-font-min-width,
+    $card-font-max-width,
+    $card-font-min-size,
+    $card-font-max-size
+  );
+  position: relative;
 }
 
 .card-title {
-  font-size: 1.2vw;
-  margin: 20px 0;
+  margin: 1.1vw 0;
   padding: 0;
 }
 
 .card-body {
-  font-size: 1.25vw;
   text-align: center;
+  position: absolute;
+  top: 50%;
+  left: 50%;
+  transform: translate(-50%);
+}
+
+.card-chart {
+  position: unset;
+  top: unset;
+  left: unset;
+  transform: unset;
+}
+
+.no-center {
+  position: unset;
+  top: unset;
+  left: unset;
+  transform: unset;
 }
 
 .card-link {
@@ -35,27 +61,21 @@ $logs-text-font-size: 10px;
 }
 
 .content-row2 {
-  position: relative;
-  top: -1vw;
-  margin-bottom: -1.5vw;
-  font-size: 1.15vw;
-}
-
-.content-row3 {
-  position: relative;
-  top: -1.5vw;
-  margin-bottom: -1.5vw;
-  font-size: 1vw;
+  margin-right: -50%;
+  transform: translate(-50%, -33%);
+  $font-size-factor: 0.8;
+  @include fluid-font-size(
+    $card-font-min-width,
+    $card-font-max-width,
+    $card-font-min-size * $font-size-factor,
+    $card-font-max-size * $font-size-factor
+  );
 }
 
 .content-highlight {
   font-weight: bold;
 }
 
-.content-medium {
-  font-size: 1.7vw;
-}
-
 .card-medium {
   min-height: $card-medium-height;
 }
@@ -71,82 +91,14 @@ $logs-text-font-size: 10px;
   text-align: left;
 }
 
-@media (max-width: 600px) {
-  .card-body {
-    margin-top: -10%;
-  }
-
-  .card-medium .card-body {
-    margin-top: -5%;
-  }
-
-  .card-medium .card-chart {
-    margin-top: -2%;
-  }
-}
-
-@media (min-width: 601px) {
-  .card-body {
-    margin-top: -5%;
-  }
-
-  .card-medium .card-body {
-    margin-top: -2%;
-  }
-
-  .card-medium .card-chart {
-    margin-top: 0;
-  }
-}
-
-@media (max-width: 767px) {
-  .card-title {
-    font-size: 4vw;
-  }
-
-  .card-body {
-    font-size: 4.5vw;
-  }
-
-  .card-medium .card-body {
-    font-size: 4.5vw;
-  }
-
-  .card-medium .text-monospace {
-    font-size: $logs-text-font-size;
-  }
-}
-
-@media (min-width: 768px) and (max-width: 991px) {
-  .card-title {
-    font-size: 2vw;
-  }
-
-  .card-medium .card-body {
-    font-size: 3vw;
-  }
-
-  .card-medium .text-monospace {
-    font-size: $logs-text-font-size;
-  }
-}
-
-@media (min-width: 768px) {
+@media (max-width: 991px) {
   .card {
-    min-height: $card-height * 1.5;
+    min-height: $card-height * 2;
   }
 
   .card-medium {
     min-height: $card-medium-height * 1.9;
   }
-
-  .card-medium .card-body {
-    margin-top: 22%;
-  }
-
-  .card-medium .card-chart {
-    margin-top: -5%;
-  }
 }
 
 @media (min-width: 992px) {
@@ -157,54 +109,16 @@ $logs-text-font-size: 10px;
   .card-medium {
     min-height: $card-medium-height * 1.5;
   }
-
-  .card-body {
-    margin-top: -10%;
-  }
-
-  .card-medium .card-body {
-    margin-top: 25%;
-  }
-
-  .card-medium .card-chart {
-    margin-top: 3%;
-  }
-}
-
-@media (min-width: 992px) and (max-width: 1199px) {
-  .content-row3 {
-    top: -0.3vw;
-  }
 }
 
 @media (min-width: 1200px) {
   .card-medium {
     min-height: $card-medium-height * 1.5;
   }
-
-  .card-body {
-    margin-top: -2%;
-  }
-
-  .card-medium .card-body {
-    margin-top: 27%;
-  }
-
-  .card-medium .card-chart {
-    margin-top: 10%;
-  }
 }
 
 @media (min-width: 1600px) {
   .card-medium {
     min-height: $card-medium-height;
   }
-
-  .card-body {
-    margin-top: 0;
-  }
-}
-
-.card-medium .no-center {
-  margin-top: 0;
 }
index f1192fdcd5a5979cd5537853fd1e68570b1e14a1..48e516ba3ec9a511ed78ce9ca3c027649266a143 100644 (file)
@@ -1,5 +1,4 @@
 <div class="info-group-title">
   {{ groupTitle }}
 </div>
-<hr class="underline" />
 <ng-content></ng-content>
index 5023de2bdb4f7457814d621eb5a76dd3fcfcb285..07d2f160552d9f016deeb076272220985cd54025 100644 (file)
@@ -1,21 +1,7 @@
 @import '../../../../defaults';
 
 .info-group-title {
-  margin: 10px 10px 0px 10px;
-  font-size: 1vw;
-}
-
-.underline {
-  border-bottom: 1px solid $color-info-group-underline;
-  margin-top: 0px;
-  margin-left: 10px;
-  margin-right: 10px;
-  margin-bottom: 20px;
-  padding: 0px;
-}
-
-@media (max-width: 767px) {
-  .info-group-title {
-    font-size: 4vw;
-  }
+  margin: 0 0 1.3vw 0.5vw;
+  padding: 0;
+  font-size: 21px;
 }
index 89815f262e65304f83bd41b29fb7663c00cd99f3..8a1109be2e1759fe09fb9490d2a927b1737d3c0e 100644 (file)
@@ -9,7 +9,7 @@
   border-bottom: 1px solid $color-transparent;
   font-size: 12px;
   &:hover {
-    background-color: $color-off-white;
+    background-color: $color-whitesmoke-gray;
   }
 }
 .select-menu-item-icon {
index 3b5a7f23c9d457355b53a4e7c8510c474d002326..9d9c09e21d3ec51dc5b234b7f74fb8b17c055056 100644 (file)
@@ -29,7 +29,7 @@ $color-grad-gray: #ededed;
 $color-light-gray: #d1d1d1;
 $color-soft-gray: #ddd;
 $color-white-gray: #eee;
-$color-off-white: #f5f5f5;
+$color-whitesmoke-gray: #f5f5f5;
 $color-solid-white: #ffffff;
 $color-transparent: rgba(0, 0, 0, 0.09);
 
@@ -72,10 +72,10 @@ $color-login-active-row-text: $color-black;
 /*Landing Page*/
 
 /*InfoGroup*/
-$color-info-group-underline: $color-off-white;
+$color-info-group-underline: $color-whitesmoke-gray;
 
 /*InfoCard*/
-$color-info-card-background: $color-off-white;
+$color-info-card-background: $color-whitesmoke-gray;
 $color-info-card-border: $color-soft-gray;
 
 /*Navigation*/
@@ -98,21 +98,21 @@ $color-helper-bg: $color-blue;
 /*Table*/
 $color-table-seperator-border: $color-transparent;
 $color-table-input-border: $color-transparent;
-$color-table-dropdown-bg: $color-off-white;
-$color-table-header-bg: $color-off-white;
+$color-table-dropdown-bg: $color-whitesmoke-gray;
+$color-table-header-bg: $color-whitesmoke-gray;
 $color-table-header-border: $color-light-gray;
 $color-table-active-row: $color-sky-blue;
 $color-table-active-row-hover: $color-light-blue;
 $color-table-progress-bar-bg: $color-sky-blue;
 $color-table-progress-bar-active: $color-blue;
-$color-table-gradient-1: $color-off-white;
+$color-table-gradient-1: $color-whitesmoke-gray;
 $color-table-gradient-2: $color-grad-gray;
 $color-table-sort: $color-blue;
 $color-table-empty-row: $color-light-yellow;
 $color-table-hover-row: $color-white-gray;
 $color-table-even-row-bg: $color-solid-white;
-$color-table-odd-row-bg: $color-off-white;
-$color-table-datatable-header: $color-off-white;
+$color-table-odd-row-bg: $color-whitesmoke-gray;
+$color-table-datatable-header: $color-whitesmoke-gray;
 
 /*Chart tooltip*/
 $color-chart-tooltip-bg: $color-transparent-black;
@@ -138,5 +138,31 @@ $color-rgw-icon: $color-blue-gray;
 
 @mixin hf {
   border-bottom: 1px solid $color-light-gray;
-  background-color: $color-off-white;
+  background-color: $color-whitesmoke-gray;
+}
+
+@function strip-unit($value) {
+  @return $value / ($value * 0 + 1);
+}
+
+@mixin fluid-font-size($min-vw, $max-vw, $min-font-size, $max-font-size) {
+  $u1: unit($min-vw);
+  $u2: unit($max-vw);
+  $u3: unit($min-font-size);
+  $u4: unit($max-font-size);
+
+  @if $u1 == $u2 and $u1 == $u3 and $u1 == $u4 {
+    & {
+      font-size: $min-font-size;
+      @media screen and (min-width: $min-vw) {
+        font-size: calc(
+          #{$min-font-size} + #{strip-unit($max-font-size - $min-font-size)} *
+            ((100vw - #{$min-vw}) / #{strip-unit($max-vw - $min-vw)})
+        );
+      }
+      @media screen and (min-width: $max-vw) {
+        font-size: $max-font-size;
+      }
+    }
+  }
 }