Project import generated by Copybara.

GitOrigin-RevId: 63746295f1a5ab5a619056791995793d65529e62
diff --git a/node_modules/mdl-ext/src/_functions.scss b/node_modules/mdl-ext/src/_functions.scss
new file mode 100644
index 0000000..2571fec
--- /dev/null
+++ b/node_modules/mdl-ext/src/_functions.scss
@@ -0,0 +1,302 @@
+///
+/// Returns the opposite direction of each direction in a list
+/// Modified from: https://css-tricks.com/snippets/sass/opposite-direction-function/
+/// @author Hugo Giraudel
+/// @param {List} $directions - List of initial directions
+/// @return {List} - List of opposite directions
+@function mdlext-opposite-direction($directions) {
+  $opposite-directions: ();
+  $direction-map: (
+    'top':    'bottom',
+    'right':  'left',
+    'bottom': 'top',
+    'left':   'right',
+    'center': 'center',
+    'ltr':    'rtl',
+    'rtl':    'ltr'
+  );
+
+  @each $direction in $directions {
+    $direction: to-lower-case($direction);
+
+    @if map-has-key($direction-map, $direction) {
+      $opposite-directions: append($opposite-directions, unquote(map-get($direction-map, $direction)));
+    }
+    @else {
+      @warn "No opposite direction can be found for `#{$direction}`. Direction omitted.";
+    }
+  }
+
+  @return $opposite-directions;
+}
+
+///
+/// Strip unit from value
+/// @author Hugo Giraudel
+/// http://hugogiraudel.com/2013/08/12/sass-functions/
+/// https://css-tricks.com/snippets/sass/strip-unit-function/
+/// @param {Number} $number - Number to remove unit from
+/// @return {Number} - Unitless number
+
+@function strip-unit($number) {
+  @return if(type-of($number) == 'number' and not unitless($number), $number / ($number * 0 + 1), $number);
+}
+
+///
+/// Clamping a number means restricting it between min and max values.
+///    4 clamped to 1-3 equals 3.
+///   -5 clamped to 1-10 equals 1.
+///   42 clamped to 10-100 equals 42.
+/// @author Hugo Giraudel
+/// http://hugogiraudel.com/2013/08/12/sass-functions/
+/// @param {Number} $value - The value to clamp
+/// @param {Number} $min - min value in range
+/// @param {Number} $max - Max value in range
+/// @return {Number} - The clamped value
+
+@function clamp($value, $min, $max) {
+  @return if($value > $max, $max, if($value < $min, $min, $value));
+}
+
+///
+/// Convert one unit into another
+/// @author Hugo Giraudel
+/// http://www.sitepoint.com/understanding-sass-units/
+/// @param {Number} $value - Initial value
+/// @param {String} $unit - Desired unit
+/// @return {Number}
+/// @throw Error if `$unit` does not exist or if units are incompatible.
+
+/* stylelint-disable */
+@function convert-unit($value, $unit) {
+  $units: (
+    'px'  : 0px,
+    'cm'  : 0cm,
+    'mm'  : 0mm,
+    '%'   : 0%,
+    'ch'  : 0ch,
+    'in'  : 0in,
+    'em'  : 0em,
+    'rem' : 0rem,
+    'pt'  : 0pt,
+    'pc'  : 0pc,
+    'ex'  : 0ex,
+    'vw'  : 0vw,
+    'vh'  : 0vh,
+    'vmin': 0vmin,
+    'vmax': 0vmax,
+    'deg' : 0deg,
+    'turn': 0turn,
+    'rad' : 0rad,
+    'grad': 0grad,
+    's'   : 0s,
+    'ms'  : 0ms,
+    'Hz'  : 0Hz,
+    'kHz' : 0kHz,
+    'dppx': 0dppx,
+    'dpcm': 0dpcm,
+    'dpi' : 0dpi,
+  );
+
+  @if map-has-key($units, $unit) {
+    @return map-get($units, $unit) + $value;
+  }
+
+  @error "Unknown unit `#{$unit}`.";
+}
+/* stylelint-enable */
+
+
+///
+/// Replace `$search` with `$replace` in `$string`
+/// @author Hugo Giraudel, http://hugogiraudel.com/2014/01/13/sass-string-replacement-function/
+/// @param {String} $string - Initial string
+/// @param {String} $search - Substring to replace
+/// @param {String} $replace ('') - New value
+/// @return {String} - Updated string
+@function str-replace($string, $search, $replace: '') {
+  $index: str-index($string, $search);
+
+  @if $index {
+    @return str-slice($string, 1, $index - 1) + $replace + str-replace(str-slice($string, $index + str-length($search)), $search, $replace);
+  }
+  @return $string;
+}
+
+///
+/// @function explode() -- split a string into a list of strings
+/// @author https://gist.github.com/danielpchen/3677421ea15dcf2579ff
+///  {string} $string: the string to be split
+///  {string} $delimiter: the boundary string
+///  @return {list} the result list
+@function explode($string, $delimiter: ',') {
+  $result: ();
+  @if $delimiter == "" {
+    @for $i from 1 through str-length($string) {
+      $result: append($result, str-slice($string, $i, $i));
+    }
+    @return $result;
+  }
+  $exploding: true;
+  @while $exploding {
+    $d-index: str-index($string, $delimiter);
+    @if $d-index {
+      @if $d-index > 1 {
+        $result: append($result, str-slice($string, 1, $d-index - 1));
+        $string: str-slice($string, $d-index + str-length($delimiter));
+      }
+      @else if $d-index == 1 {
+        $string: str-slice($string, 1, $d-index + str-length($delimiter));
+      }
+      @else {
+        $result: append($result, $string);
+        $exploding: false;
+      }
+    }
+    @else {
+      $result: append($result, $string);
+      $exploding: false;
+    }
+  }
+  @return $result;
+}
+
+///
+/// Add `$unit` to `$value`
+/// @author Hugo Giraudel
+///
+/// @param {Number} $value - Value to add unit to
+/// @param {String} $unit - String representation of the unit
+///
+/// @return {Number} - `$value` expressed in `$unit`
+/// @throw Error if `$unit` does not exist or if units are incompatible.
+///
+@function to-length($value, $unit) {
+  $units: (
+    'px'  : 1px,
+    'cm'  : 1cm,
+    'mm'  : 1mm,
+    '%'   : 1%,
+    'ch'  : 1ch,
+    'pc'  : 1pc,
+    'in'  : 1in,
+    'em'  : 1em,
+    'rem' : 1rem,
+    'pt'  : 1pt,
+    'ex'  : 1ex,
+    'vw'  : 1vw,
+    'vh'  : 1vh,
+    'vmin': 1vmin,
+    'vmax': 1vmax
+  );
+
+  @if not index(map-keys($units), $unit) {
+    @error('Invalid unit `#{$unit}`.');
+  }
+
+  @return $value * map-get($units, $unit);
+}
+
+///
+/// Casts a string into a number
+///
+/// @author Hugo Giraudel
+// @param {String | Number} $value - Value to be parsed
+///
+/// @return {Number}
+/// @throw Error if `$value` is not a number or a string.
+///
+@function to-number($value) {
+  @if type-of($value) == 'number' {
+    @return $value;
+  }
+  @else if type-of($value) != 'string' {
+    @error('Value for `to-number` should be a number or a string.');
+  }
+
+  $result: 0;
+  $digits: 0;
+  $minus: str-slice($value, 1, 1) == '-';
+  $numbers: ('0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9);
+
+  @for $i from if($minus, 2, 1) through str-length($value) {
+    $character: str-slice($value, $i, $i);
+
+    @if not (index(map-keys($numbers), $character) or $character == '.') {
+      @return to-length(if($minus, -$result, $result), str-slice($value, $i));
+    }
+
+    @if $character == '.' {
+      $digits: 1;
+    }
+    @else if $digits == 0 {
+      $result: $result * 10 + map-get($numbers, $character);
+    }
+    @else {
+      $digits: $digits * 10;
+      $result: $result + map-get($numbers, $character) / $digits;
+    }
+  }
+
+  @return if($minus, -$result, $result);
+}
+
+///
+/// Convert `$rgb-string` to a number list
+/// @author Leif Olsen
+/// @param {String | Number} $value - Value to be parsed
+/// @return {list} the rgb number list
+/// @throw Error if `$value` is not a number, color or a string.
+@function rgb-string-to-numbers($value) {
+  @if type-of($value) == 'number' or type-of($value) == 'color' {
+    @return $value;
+  }
+  @else if type-of($value) != 'string' {
+    @error('Value for `rgb-string-to-numbers` should be a number or a string.');
+  }
+
+  $s: str-replace($value, "rgba");
+  $s: str-replace($s, "rgb");
+  $s: str-replace($s, "(");
+  $s: str-replace($s, ")");
+  $s: str-replace($s, " ");
+  $l: explode($s);
+  $result: ();
+  @for $i from 1 through length($l) {
+    $result: append($result, to-number(nth($l, $i)));
+  }
+  @return $result;
+}
+
+///
+/// Convert `$rgb-string` to a corresponding hex value
+/// @author Leif Olsen
+/// @param {String | Number} $value - Value to be parsed
+/// @return {number} the rgb hex value
+/// @throw Error if `$value` is not a number, color or a string.
+@function rgb-string-to-hex($value) {
+  @if type-of($value) == 'number' or type-of($value) == 'color' {
+    @return $value;
+  }
+  @else if type-of($value) != 'string' {
+    @error('Value for `rgb-string-to-numbers` should be a number or a string.');
+  }
+  $l: rgb-string-to-numbers($value);
+  @return rgb(nth($l, 1), nth($l, 2), nth($l, 3));
+}
+
+
+///
+/// Convert hex color to a coresponding `$rgb-string`
+/// @author https://github.com/google/material-design-lite/issues/1689
+/// @param {Number} $hexColor - Value to convert
+/// @return {String} the rgb string value
+///
+/// @example - $color-primary: hex-to-string(#333);
+@function hex-to-rgb-string($hexColor) {
+  // 0.999999 val in alpha actually compiles to 1.0
+  $rgbaVal:  inspect(rgba($hexColor, 0.9999999));
+
+  // slice substring between 'rgba(' and '1.0)'
+  @return str-slice($rgbaVal, 6, str-length($rgbaVal)-4);
+}
diff --git a/node_modules/mdl-ext/src/_mixins.scss b/node_modules/mdl-ext/src/_mixins.scss
new file mode 100644
index 0000000..cf274ab
--- /dev/null
+++ b/node_modules/mdl-ext/src/_mixins.scss
@@ -0,0 +1,211 @@
+@import "functions";
+
+/// Triangle helper mixin
+/// Modified from: http://blustemy.io/drawing-pure-css-arrows-with-mixins/
+///                https://css-tricks.com/snippets/sass/css-triangle-mixin/
+/// @param {Direction} $direction - Triangle direction, either `top`, `right`, `bottom` or `left`
+/// @param {Color} $color [currentcolor] - Triangle color
+/// @param {Length} $size [1em] - Triangle size
+@mixin mdlext-arrow($direction: bottom, $base-width: 15px, $length: 10px, $color: inherit, $font-size: inherit) {
+  content: '';
+  width: 0;
+  height: 0;
+  font-size: $font-size;
+  line-height: $font-size;
+  border-#{mdlext-opposite-direction($direction)}: $length solid $color;
+  border-#{mdlext-opposite-direction($direction)}-width: $length;
+  border-#{mdlext-opposite-direction($direction)}-style: solid;
+  border-#{mdlext-opposite-direction($direction)}-color: $color;
+
+  $perpendicular-borders: ($base-width / 2) solid transparent;
+
+  @if $direction == top or $direction == bottom {
+    border-left: $perpendicular-borders;
+    border-right: $perpendicular-borders;
+  }
+  @else if $direction == right or $direction == left {
+    border-bottom: $perpendicular-borders;
+    border-top: $perpendicular-borders;
+  }
+}
+
+/// Hide element while making it readable for screen readers
+/// Copied from HTML5Boilerplate:
+/// https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css#L119-L133
+@mixin mdlext-visually-hidden() {
+  border: 0;
+  clip: rect(0 0 0 0);
+  height: 1px;
+  margin: -1px;
+  overflow: hidden;
+  padding: 0;
+  position: absolute;
+  width: 1px;
+}
+
+
+/// Toggle for aria-expanded attribute
+///
+/// @author Leif Olsen
+/// @param {Font} $font-family ['Material Icons'] - Font family
+/// @param {Length} $font-size [24px] - Font size
+/// @param {string} $icon ['+'] - icon to display when 'aria-expanded="false"'
+/// @param {string} $icon-expanded ['-'] - icon to display when 'aria-expanded="true"'
+/// @link https://github.com/google/material-design-icons Modified from '.material-icons' class
+/// @param {Length} $icon-offset [0] - Icon offset
+///
+/// @example - +/- toggle
+///   .plus-minus {
+///     @include mdlext-aria-expanded-toggle($font-family: inherit, $font-size: inherit);
+///   }
+///   <div aria-expanded="false">
+///     <i class="plus-minus"></i>
+///   </div>
+///
+/// @example - Material Icons, expand-more/expand_less
+///   .more-less {
+///     @include mdlext-aria-expanded-toggle($content: 'expand_more', $content-expanded: 'expand_less');
+///   }
+///   <div aria-expanded="true">
+///     <i class="more-less"></i>
+///   </div>
+
+@mixin mdlext-aria-expanded-toggle($font-family: 'Material Icons', $font-size: 24px, $icon: '+', $icon-expanded: '-', $icon-offset: 0) {
+  font-family: $font-family;
+  font-weight: inherit;
+  font-style: inherit;
+  font-size: $font-size;  // Preferred icon size
+  display: inline-block;
+  width: 1em;
+  height: 1em;
+  line-height: 1;
+  text-transform: none;
+  letter-spacing: normal;
+  word-wrap: normal;
+  white-space: nowrap;
+  direction: ltr;
+  vertical-align: middle;
+
+  // Support for all WebKit browsers.
+  -webkit-font-smoothing: antialiased;
+  -webkit-font-feature-settings: 'liga';
+
+  // Support for Safari and Chrome.
+  text-rendering: optimizeLegibility;
+
+  // Support for Firefox.
+  -moz-osx-font-smoothing: grayscale;
+
+  // Support for IE.
+  font-feature-settings: 'liga';
+
+  &::after {
+    content: $icon;
+    margin-left: $icon-offset;
+  }
+
+  [aria-expanded='true'] > & {
+    &::after {
+      content: $icon-expanded;
+      margin-left: $icon-offset;
+    }
+  }
+}
+
+
+/// Keyframe mixin
+/// Modified from: http://sassbreak.com/nested-keyframe-rules-sass/
+/// Modified from: http://sassbreak.com/sass-tools-and-snippets/
+///
+/// @example
+///
+/// .some-element {
+///   animation: 10s linear infinite;
+///
+///   @include mdlext-animation-keyframes {
+///     from {
+///       background-position: 0% 0%;
+///     }
+///     to {
+///       background-position: 114.2857% 0%;
+///     }
+///   }
+/// }
+
+@mixin mdlext-animation-keyframes {
+  $animation-name: unique-id();
+  animation-name: $animation-name;
+
+  @keyframes #{$animation-name} {
+    @content;
+  }
+}
+
+
+/// Flexible title mixin
+/// A flexible title consists of three regions, left, middle and right.
+/// The left and right regions are optional and will typically contain state icons
+/// or act as a toolbar. The middle region should contain the title text.
+///
+/// @author Leif Olsen
+/// @param {String} $class - class name
+/// @gutter {Length} [8px] - horizontal spacing between title elements
+///
+/// @example
+///
+/// @include mdlext-flexible-title(my-title) {
+///   overflow: hidden;
+///   background-color: yellow;
+///   &__text {
+///     font-size: 20px;
+///     letter-spacing: 0.02em;
+///     font-weight: 400;
+///     line-height: 1.1;
+///   }
+/// }
+///
+/// <header class="my-title">
+///   <i class="material-icons" role="presentation" style="font-size: 28px;">info</i>
+///   <h2 class="my-title__text">A title</h2>
+///   <span class="my-title__spacer"></span>
+///   <i class="mdlext-aria-expanded-more-less" role="presentation" style="font-size: 28px;"></i>
+/// </header>
+
+@mixin mdlext-flexible-title($class, $gutter: 8px) {
+  .#{$class} {
+    box-sizing: border-box;
+    position: relative;
+    width: 100%;
+    display: flex;
+    align-self: stretch;
+    align-items: center;
+    margin: 0;
+    padding: 0 $gutter;
+
+    &__text,
+    &__text > * {
+      white-space: nowrap;
+      overflow: hidden;
+      text-overflow: ellipsis;
+    }
+
+    > * {
+      box-sizing: border-box;
+      margin: 0;
+      padding: 0 $gutter 0 0;
+    }
+
+    > *:last-child {
+      padding-right: 0;
+    }
+
+    // Used to align elements inside a header or drawer, by growing to fill
+    // remaining space. Commonly used for aligning elements to the right.
+    &__spacer {
+      flex: 1;
+    }
+
+    @content;
+  }
+}
+
diff --git a/node_modules/mdl-ext/src/_variables.scss b/node_modules/mdl-ext/src/_variables.scss
new file mode 100644
index 0000000..908b337
--- /dev/null
+++ b/node_modules/mdl-ext/src/_variables.scss
@@ -0,0 +1,581 @@
+/**
+ * Copyright 2016 Leif Olsen. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+@import "functions";
+
+// ----------------------------------------------------------------
+// Sample colors
+// ----------------------------------------------------------------
+$mdlext-palette-amber-50:                         #FFF8E1;
+$mdlext-palette-amber-100:                        #FFECB3;
+$mdlext-palette-amber-500:                        #FFC107;
+$mdlext-palette-amber-700:                        #FFA000;
+$mdlext-palette-blue-grey-500:                    #607D8B;
+$mdlext-palette-deep-orange-500:                  #FF5722;
+$mdlext-palette-deep-purple-100:                  #D1C4E9;
+$mdlext-palette-deep-purple-500:                  #512DA8;
+$mdlext-palette-deep-purple-700:                  #673AB7;
+$mdlext-palette-green-50:                         #E8F5E9;
+$mdlext-palette-green-100:                        #C8E6C9;
+$mdlext-palette-green-500:                        #4CAF50;
+$mdlext-palette-green-700:                        #388E3C;
+$mdlext-palette-grey-50:                          #FAFAFA;
+$mdlext-palette-grey-100:                         #F5F5F5;
+$mdlext-palette-grey-200:                         #EEEEEE;
+$mdlext-palette-grey-300:                         #E0E0E0;
+$mdlext-palette-grey-400:                         #BDBDBD;
+$mdlext-palette-grey-500:                         #9E9E9E;
+$mdlext-palette-grey-600:                         #757575;
+$mdlext-palette-grey-700:                         #616161;
+$mdlext-palette-grey-800:                         #424242;
+$mdlext-palette-grey-900:                         #212121;
+$mdlext-palette-indigo-A200:                      #536DFE;
+$mdlext-palette-light-blue-500:                   #03A9F4;
+$mdlext-palette-light-green-500:                  #8BC34A;
+$mdlext-palette-pink-500:                         #E91E63;
+$mdlext-palette-pink-700:                         #C2185B;
+$mdlext-palette-pink-A400:                        #F50057;
+$mdlext-palette-purple-A200:                      #E040FB;
+$mdlext-palette-red-700:                          #D32F2F;
+$mdlext-palette-red-A200:                         #FF5252;
+$mdlext-palette-red-A400:                         #FF1744;
+$mdlext-palette-yellow-500:                       #FFEB3B;
+$mdlext-color-black:                              #000000;
+$mdlext-color-white:                              #FFFFFF;
+
+
+/* ==========   Sticky Header   ========== */
+$mdlext-sticky-header-background-color           : transparent !default;
+$mdlext-sticky-header-background-color-scroll    : transparent !default;
+$mdlext-sticky-header-gradient-color             : rgb-string-to-hex($color-primary) !default;
+$mdlext-sticky-header-gradient-color-start       : $mdlext-sticky-header-gradient-color !default;
+$mdlext-sticky-header-gradient-color-end         : $mdlext-sticky-header-gradient-color-start !default;
+$mdlext-sticky-header-gradient-color-scroll-start: rgba($mdlext-sticky-header-gradient-color, 0.98) !default;
+$mdlext-sticky-header-gradient-color-scroll-end  : rgba($mdlext-sticky-header-gradient-color, 0.95) !default;
+
+// Background shorthand
+/* stylelint-disable */
+$mdlext-sticky-header-background                 : $mdlext-sticky-header-background-color
+                                                   linear-gradient(to bottom,
+                                                      $mdlext-sticky-header-gradient-color-start 0,
+                                                      $mdlext-sticky-header-gradient-color-end 100%) !default;
+
+// Background shorthand when content is scrolling
+$mdlext-sticky-header-background-scroll          : $mdlext-sticky-header-background-color-scroll
+                                                   linear-gradient(to bottom,
+                                                      $mdlext-sticky-header-gradient-color-scroll-start 100%,
+                                                      $mdlext-sticky-header-gradient-color-scroll-end 100%) !default;
+/* stylelint-enable */
+
+/* ==========     Accordion     ========== */
+$mdlext-accordion-header-background-color-base   : $mdlext-palette-grey-500 !default;
+$mdlext-accordion-header-background-color        : rgba($mdlext-accordion-header-background-color-base, 0.20) !default;
+$mdlext-accordion-header-background-open-color   : rgba($mdlext-accordion-header-background-color-base, 0.30) !default;
+$mdlext-accordion-header-background-active-color : rgba($mdlext-accordion-header-background-color-base, 0.40) !default;
+$mdlext-accordion-header-border-color            : rgba($mdlext-accordion-header-background-color-base, 0.50) !default;
+$mdlext-accordion-header-background-hover-color  : rgba($mdlext-accordion-header-background-color-base, 0.40) !default;
+$mdlext-accordion-header-focus-outline-color     : invert !default;
+$mdlext-accordion-header-disabled-color          : rgba($mdlext-accordion-header-background-color-base, 0.12) !default;
+$mdlext-accordion-header-secondary-color         : $mdlext-color-black !default;
+$mdlext-accordion-header-secondary-color-disabled: rgba($mdlext-color-black, 0.26) !default;
+$mdlext-accordion-header-highlight-color         : darken($mdlext-accordion-header-border-color, 3%) !default;
+$mdlext-accordion-ripple-color                   : rgba(rgb-string-to-hex($color-accent-contrast), 0.5) !default;
+$mdlext-accordion-header-padding                 : 8px !default;
+$mdlext-accordion-header-height                  : 56px !default;
+$mdlext-accordion-content-padding                : $mdlext-accordion-header-padding !default;
+$mdlext-accordion-content-color                  : inherit !default;
+$mdlext-accordion-content-background-color       : transparent !default;
+
+
+/* ==========     Dialog     ========== */
+$mdlext-dialog-padding           : 0;
+$mdlext-dialog-background-color  : transparent !default;
+$mdlext-dialog-backdrop-color    : rgba(0, 0, 0, 0.86) !default;
+$mdlext-dialog-open-animation    : 0.5s 0.2s forwards !default;
+$mdlext-dialog-backdrop-animation: 0.2s forwards !default;
+
+
+/* ==========     Lightbox     ========== */
+$mdlext-lightbox-background-color           : $card-background-color !default;
+$mdlext-lightbox-border                     : 0 !default;
+$mdlext-lightbox-border-radius              : 0 !default;
+$mdlext-lightbox-figure-margin              : 0 !default;
+$mdlext-lightbox-figure-padding             : 0 !default;
+$mdlext-lightbox-figcaption-background-color: rgba(255, 255, 255, 0.76) !default;
+$mdlext-lightbox-footer-background-color    : rgba(255, 255, 255, 0.86) !default;
+
+
+/* ==========  Lightboard  ========== */
+$mdlext-lightboard-medium-small-breakpoint     : $grid-tablet-breakpoint !default;          // 480
+$mdlext-lightboard-medium-breakpoint           : $grid-tablet-breakpoint + 180px !default;  // 480 + 180
+$mdlext-lightboard-medium-large-breakpoint     : $grid-desktop-breakpoint !default;         // 840
+$mdlext-lightboard-large-breakpoint            : $grid-desktop-breakpoint + 360px !default; // 840+360
+
+$mdlext-lightboard-small-gutter                : 2px !default;
+$mdlext-lightboard-small-margin                : 0 !default;
+$mdlext-lightboard-small-columns               : 2 !default;
+$mdlext-lightboard-small-frame-width           : 8px !default;
+
+$mdlext-lightboard-medium-small-gutter         : 4px !default;
+$mdlext-lightboard-medium-small-margin         : 0 !default;
+$mdlext-lightboard-medium-small-columns        : 4 !default;
+$mdlext-lightboard-medium-small-frame-width    : 8px !default;
+
+$mdlext-lightboard-medium-gutter               : 4px !default;
+$mdlext-lightboard-medium-margin               : 0 !default;
+$mdlext-lightboard-medium-columns              : 5 !default;
+$mdlext-lightboard-medium-frame-width          : 8px !default;
+
+$mdlext-lightboard-medium-large-gutter         : 8px !default;
+$mdlext-lightboard-medium-large-margin         : 0 !default;
+$mdlext-lightboard-medium-large-columns        : 6 !default;
+$mdlext-lightboard-medium-large-frame-width    : 12px !default;
+
+$mdlext-lightboard-large-gutter                : 8px !default;
+$mdlext-lightboard-large-margin                : 0 !default;
+$mdlext-lightboard-large-columns               : 7 !default;
+$mdlext-lightboard-large-frame-width           : 12px !default;
+
+$mdlext-lightboard-slide-max-size              : 250px !default;
+$mdlext-lightboard-slide-border-color          : #D8D8D8 !default;
+$mdlext-lightboard-slide-background-color      : #F8F8F8 !default;
+$mdlext-lightboard-slide-border-radius         : 5px !default;
+$mdlext-lightboard-slide-inner-border-radius   : 3px !default;
+$mdlext-lightboard-slide-box-shadow            : 2px 2px 6px -1px rgba(219, 215, 219, 0.5) !default;
+$mdlext-lightboard-slide-border-color-hover    : #B8B8B8 !default;
+$mdlext-lightboard-slide-background-color-hover: #E8E8E8 !default;
+$mdlext-lightboard-slide-active-bacground-color: #E8E8E8 !default;
+$mdlext-lightboard-slide-box-shadow-hover      : 2px 2px 12px -1px rgba(219, 215, 219, 1) !default;
+$mdlext-lightboard-ripple-color                : $tab-highlight-color !default;
+$mdlext-lightboard-focus-outline-color         : inherit !default;
+$mdlext-lightboard-figcaption-text-color       : rgb-string-to-hex($palette-grey-400) !default;
+
+
+/* ==========  Carousel  ========== */
+$mdlext-carousel-slide-border-top-width        : 2px !default;
+$mdlext-carousel-slide-border-top-color        : rgb-string-to-hex($color-accent) !default;
+$mdlext-carousel-slide-margin-horizontal       : 0;
+$mdlext-carousel-slide-figcaption-color        : $mdlext-lightboard-figcaption-text-color !default;
+$mdlext-carousel-slide-ripple-color            : $mdlext-lightboard-ripple-color !default;
+
+
+/* ==========  Bordered fields  ========== */
+$mdlext-bordered-field-vertical-spacing-top           : 0 !default;
+$mdlext-bordered-field-vertical-spacing-bottom        : $input-text-vertical-spacing !default;
+
+$mdlext-bordered-field-input-text-font-size           : $input-text-font-size !default;
+$mdlext-bordered-field-font-weight                    : normal !default;
+$mdlext-bordered-field-border-width                   : 1px !default;
+$mdlext-bordered-field-border-radius                  : 3px !default;
+$mdlext-bordered-field-padding                        : $input-text-padding + 4px !default;
+$mdlext-bordered-field-padding-top                    : $input-text-vertical-spacing !default;
+$mdlext-bordered-field-padding-bottom                 : $input-text-padding !default;
+
+$mdlext-bordered-field-input-text-color               : inherit !default;
+$mdlext-bordered-field-border-color                   : rgba($mdlext-color-black, 0.26) !default;
+$mdlext-bordered-field-background-color               : rgba(#FFFFFF, 0.2) !default;
+$mdlext-bordered-field-focus-border-color             : rgb-string-to-hex($color-primary) !default;
+$mdlext-bordered-field-focus-background-color         : rgba(#EEEEEE, 0.2) !default;
+
+$mdlext-bordered-field-input-text-disabled-text-color : rgba($mdlext-color-black, 0.12) !default;
+$mdlext-bordered-field-disabled-border-color          : rgba($mdlext-color-black, 0.12) !default;
+$mdlext-bordered-field-disabled-background-color      : $mdlext-bordered-field-background-color !default;
+
+$mdlext-bordered-field-input-text-error-color         : $mdlext-bordered-field-input-text-color !default;
+$mdlext-bordered-field-error-border-color             : rgb-string-to-hex($input-text-error-color) !default;
+$mdlext-bordered-field-error-background-color         : rgba(lighten($mdlext-bordered-field-error-border-color, 50%), 0.5) !default;
+$mdlext-bordered-field-error-focus-border-color       : darken($mdlext-bordered-field-error-border-color, 10%) !default;
+$mdlext-bordered-field-error-focus-background-color   : $mdlext-bordered-field-error-background-color !default;
+
+$mdlext-bordered-field-input-text-label-color         : rgba($mdlext-color-black, 0.26) !default;
+$mdlext-bordered-field-input-text-label-focus-color   : $mdlext-bordered-field-focus-border-color !default;
+$mdlext-bordered-field-input-text-label-error-color   : $mdlext-bordered-field-error-border-color !default;
+$mdlext-bordered-field-input-text-label-disabled-color: rgba($mdlext-color-black, 0.12) !default;
+
+$mdlext-bordered-field-label-font-size                : $mdlext-bordered-field-input-text-font-size !default;
+$mdlext-bordered-field-floating-label-font-size       : $input-text-floating-label-fontsize !default;
+$mdlext-bordered-field-floating-label-font-weight     : normal !default;
+
+$mdlext-bordered-field-height                         : $mdlext-bordered-field-padding-top + $mdlext-bordered-field-padding-bottom + $mdlext-bordered-field-input-text-font-size + 6px !default;
+$mdlext-bordered-field-floating-label-focus-bottom    : $mdlext-bordered-field-height - $mdlext-bordered-field-floating-label-font-size - $mdlext-bordered-field-padding-top/2 !default;
+
+
+// MDL can not handle required attribute properly. Planned for MDL-v2
+//$mdlext-bordered-field-required-border-color          : rgba(rgb-string-to-hex($color-accent), 0.8) !default;
+//$mdlext-bordered-field-required-background-color      : $mdlext-bordered-field-background-color !default;
+//$mdlext-bordered-field-required-focus-border-color    : rgba(rgb-string-to-hex($color-accent), 0.8) !default;
+//$mdlext-bordered-field-required-focus-background-color: $mdlext-bordered-field-background-color !default;
+//$mdlext-bordered-field-label-required-color           : $mdlext-bordered-field-required-border-color !default;
+
+
+
+/* ==========  Color Themes  ========== */
+
+// ----------------------------------------------------------------
+// Light Color Theme.
+// ----------------------------------------------------------------
+$mdlext-light-color-primary:                      #4CAF50 !default;
+$mdlext-light-color-primary-dark:                 #388E3C !default;
+$mdlext-light-color-primary-light:                #4CAF50 !default;  // Fallback color. Set to color-primary if fallback is not needed
+$mdlext-light-color-primary-contrast:             #C8E6C9 !default;  // text color on primary/primary dark background
+$mdlext-light-color-accent:                       #E040FB !default;
+$mdlext-light-color-accent-light:                 #E040FB !default;  // Fallback color. Set to color-accent if fallback is not needed
+$mdlext-light-color-accent-contrast:              #FAFAFA !default;
+
+$mdlext-light-content-background-color:           #FAFAFA !default;                         // background color on content (paper/card) background
+$mdlext-light-text-color-primary:                 rgba($mdlext-color-black, 0.87) !default; // text color on content (paper/card) background
+$mdlext-light-text-color-secondary:               rgba($mdlext-color-black, 0.54) !default; // text color on content (paper/card) background
+$mdlext-light-text-color-disabled:                rgba($mdlext-color-black, 0.38) !default; // disabled text, hint text, and icons
+$mdlext-light-divider-color:                      rgba($mdlext-color-black, 0.12) !default; // -> $card-border-color
+$mdlext-light-error-color:                        #D32F2F !default;
+
+// Anchor
+$mdlext-light-text-link-color:                    $mdlext-light-color-accent !default;
+
+// Card
+$mdlext-light-card-background-color:              $mdlext-light-content-background-color !default;
+$mdlext-light-card-text-color:                    $mdlext-light-text-color-primary !default;
+$mdlext-light-card-image-placeholder-color:       $mdlext-light-color-accent !default;
+$mdlext-light-card-supporting-text-text-color:    rgba($mdlext-color-black, 0.54) !default;
+$mdlext-light-card-border-color:                  rgba(0, 0, 0, 0.1) !default;
+$mdlext-light-card-subtitle-color:                rgba($mdlext-color-black, 0.54) !default;
+
+//  Item
+
+// Default Item Colors
+$mdlext-light-default-item-text-color:            rgba($mdlext-color-black, 0.87) !default;
+$mdlext-light-default-item-outline-color:         $mdlext-palette-grey-400 !default;
+$mdlext-light-default-item-hover-bg-color:        $mdlext-palette-grey-200 !default;
+$mdlext-light-default-item-focus-bg-color:        $mdlext-palette-grey-200 !default;
+$mdlext-light-default-item-active-bg-color:       $mdlext-palette-grey-300 !default;
+$mdlext-light-default-item-divider-color:         rgba($mdlext-color-black, 0.12) !default;
+
+// Disabled Button Colors
+$mdlext-light-disabled-item-text-color:           $mdlext-palette-grey-400 !default;
+
+// Dropdown menu / menu-button
+$mdlext-light-default-dropdown-bg-color:          $mdlext-color-white !default;
+
+// Badge
+$mdlext-light-badge-color:                        $mdlext-light-color-accent-contrast !default;
+$mdlext-light-badge-color-inverse:                $mdlext-light-color-accent !default;
+$mdlext-light-badge-background:                   $mdlext-light-color-accent !default;
+$mdlext-light-badge-background-inverse:           $mdlext-light-color-accent-contrast !default;
+
+// Default button colors.
+$mdlext-light-button-primary-color:               rgba($mdlext-palette-grey-500, 0.20) !default;
+$mdlext-light-button-secondary-color:             $mdlext-color-black !default;
+$mdlext-light-button-hover-color:                 $mdlext-light-button-primary-color !default;
+$mdlext-light-button-active-color:                rgba($mdlext-palette-grey-500, 0.40) !default;
+$mdlext-light-button-focus-color:                 rgba($mdlext-color-black, 0.12) !default;
+
+// Colored button colors.
+$mdlext-light-button-primary-color-alt:           $mdlext-light-color-primary-light !default;
+$mdlext-light-button-secondary-color-alt:         $mdlext-light-color-primary-contrast !default;
+$mdlext-light-button-hover-color-alt:             darken($mdlext-light-color-primary-light, 10%) !default;
+$mdlext-light-button-active-color-alt:            darken($mdlext-light-color-primary-light, 10%) !default;
+$mdlext-light-button-focus-color-alt:             $mdlext-light-button-focus-color !default;
+
+// Ripple color for colored raised buttons.
+$mdlext-light-button-ripple-color-alt:            $mdlext-light-color-primary-contrast !default;
+
+// Disabled button colors.
+$mdlext-light-button-primary-color-disabled:      rgba($mdlext-color-black, 0.12) !default;
+$mdlext-light-button-secondary-color-disabled:    rgba($mdlext-color-black, 0.26) !default;
+
+// FAB colors and sizes.
+$mdlext-light-button-fab-color-alt:               $mdlext-light-color-accent !default;
+$mdlext-light-button-fab-hover-color-alt:         $mdlext-light-color-accent !default;
+$mdlext-light-button-fab-active-color-alt:        $mdlext-light-color-accent !default;
+$mdlext-light-button-fab-text-color-alt:          $mdlext-light-color-accent-contrast !default;
+$mdlext-light-button-fab-ripple-color-alt:        $mdlext-light-color-accent-contrast !default;
+
+// Slider
+$mdlext-light-range-bg-color:                     rgba($mdlext-color-black, 0.26) !default;
+$mdlext-light-range-color:                        $mdlext-light-color-accent-light !default;
+$mdlext-light-range-faded-color:                  rgba($mdlext-light-color-accent-light, 0.26) !default;
+$mdlext-light-range-bg-focus-color:               rgba($mdlext-color-black, 0.12) !default;
+
+// Textfields
+$mdlext-light-input-text-background-color:        transparent !default;
+$mdlext-light-input-text-label-color:             rgba($mdlext-color-black, 0.54) !default;
+$mdlext-light-input-text-bottom-border-color:     rgba($mdlext-color-black, 0.26) !default;
+$mdlext-light-input-text-highlight-color:         $mdlext-light-color-accent-light !default;
+$mdlext-light-input-text-disabled-color:          rgba($mdlext-color-black, 0.12) !default;
+$mdlext-light-input-text-disabled-text-color:     rgba($mdlext-color-black, 0.26) !default;
+$mdlext-light-input-text-error-color:             $mdlext-light-error-color !default;
+
+// Checkboxes
+$mdlext-light-checkbox-color:                     $mdlext-light-color-accent-light !default;
+$mdlext-light-checkbox-off-color:                 rgba($mdlext-color-black, 0.54) !default;
+$mdlext-light-checkbox-disabled-color:            rgba($mdlext-color-black, 0.26) !default;
+$mdlext-light-checkbox-focus-color:               rgba($mdlext-light-color-accent-light, 0.26) !default;
+
+// Icon Toggles
+$mdlext-light-icon-toggle-color:                  $mdlext-palette-grey-700 !default;
+$mdlext-light-icon-toggle-focus-color:            $mdlext-light-button-focus-color !default;
+$mdlext-light-icon-toggle-checked-color:          $mdlext-light-color-accent-light !default;
+$mdlext-light-icon-toggle-checked-focus-color:    rgba($mdlext-light-color-accent-light, 0.26) !default;
+$mdlext-light-icon-toggle-disabled-color:         rgba($mdlext-color-black, 0.26) !default;
+
+// Radio Buttons
+$mdlext-light-radio-color:                        $mdlext-light-color-accent-light !default;
+$mdlext-light-radio-off-color:                    rgba($mdlext-color-black, 0.54) !default;
+$mdlext-light-radio-disabled-color:               rgba($mdlext-color-black, 0.26) !default;
+
+// Switches
+$mdlext-light-switch-color:                       $mdlext-light-color-accent-light !default;
+$mdlext-light-switch-faded-color:                 rgba($mdlext-light-color-accent-light, 0.26) !default;
+$mdlext-light-switch-thumb-color:                 $mdlext-light-switch-color !default;
+$mdlext-light-switch-track-color:                 rgba($mdlext-light-color-accent-light, 0.54) !default;
+$mdlext-light-switch-off-thumb-color:             $mdlext-palette-grey-50 !default;
+$mdlext-light-switch-off-track-color:             rgba($mdlext-color-black, 0.26) !default;
+$mdlext-light-switch-disabled-thumb-color:        $mdlext-palette-grey-400 !default;
+$mdlext-light-switch-disabled-track-color:        rgba($mdlext-color-black, 0.12) !default;
+
+// Data table
+$mdlext-light-data-table-background-color:               $mdlext-light-content-background-color !default;
+$mdlext-light-data-table-header-color:                   rgba($mdlext-color-black, 0.54) !default;
+$mdlext-light-data-table-header-sorted-color:            rgba($mdlext-color-black, 0.87) !default;
+$mdlext-light-data-table-header-sorted-icon-hover-color: rgba($mdlext-color-black, 0.26) !default;
+$mdlext-light-data-table-hover-color:                    $mdlext-palette-grey-200 !default;
+$mdlext-light-data-table-selection-color:                $mdlext-palette-grey-200 !default;
+$mdlext-light-data-table-divider-color:                  rgba($mdlext-color-black, 0.12) !default;
+$mdlext-light-data-table-dividers:                       1px solid $mdlext-light-data-table-divider-color !default;
+
+
+// Selectfield
+// Uses variables from textfield
+$mdlext-selectfield-arrow-width: 0.7em;
+$mdlext-selectfield-arrow-length: 0.5em;
+
+
+// Accordion
+$mdlext-light-accordion-header-background-color-base   : $mdlext-palette-grey-600 !default;
+$mdlext-light-accordion-header-background-color        : rgba($mdlext-light-accordion-header-background-color-base, 0.20) !default;
+$mdlext-light-accordion-header-background-open-color   : rgba($mdlext-light-accordion-header-background-color-base, 0.30) !default;
+$mdlext-light-accordion-header-background-active-color : rgba($mdlext-light-accordion-header-background-color-base, 0.40) !default;
+$mdlext-light-accordion-header-border-color            : rgba($mdlext-light-accordion-header-background-color-base, 0.50) !default;
+$mdlext-light-accordion-header-background-hover-color  : rgba($mdlext-light-accordion-header-background-color-base, 0.40) !default;
+$mdlext-light-accordion-header-focus-outline-color     : darken($mdlext-light-accordion-header-border-color, 3%) !default;
+$mdlext-light-accordion-header-disabled-color          : rgba($mdlext-light-accordion-header-background-color-base, 0.12) !default;
+$mdlext-light-accordion-header-secondary-color         : $mdlext-color-black !default;
+$mdlext-light-accordion-header-secondary-color-disabled: rgba($mdlext-color-black, 0.26) !default;
+$mdlext-light-accordion-header-highlight-color         : darken($mdlext-light-accordion-header-border-color, 6%) !default;
+$mdlext-light-accordion-ripple-color                   : rgba($mdlext-light-accordion-header-background-color-base, 0.4) !default;
+$mdlext-light-accordion-content-color                  : inherit !default;
+$mdlext-light-accordion-content-background-color       : transparent !default;
+
+
+// Bordered fields
+$mdlext-light-bordered-field-input-text-color               : inherit !default;
+$mdlext-light-bordered-field-border-color                   : $mdlext-light-input-text-bottom-border-color !default;
+$mdlext-light-bordered-field-background-color               : rgba($mdlext-light-content-background-color, 0.1) !default;
+$mdlext-light-bordered-field-focus-border-color             : $mdlext-light-color-accent-light !default;
+$mdlext-light-bordered-field-focus-background-color         : rgba(darken($mdlext-light-bordered-field-background-color, 10%), 0.1) !default;
+
+$mdlext-light-bordered-field-input-text-disabled-text-color : $mdlext-light-input-text-disabled-text-color;
+$mdlext-light-bordered-field-disabled-border-color          : $mdlext-light-input-text-disabled-color !default;
+$mdlext-light-bordered-field-disabled-background-color      : $mdlext-light-bordered-field-background-color !default;
+
+$mdlext-light-bordered-field-input-text-error-color         : $mdlext-light-bordered-field-input-text-color !default;
+$mdlext-light-bordered-field-error-border-color             : $mdlext-light-input-text-error-color !default;
+$mdlext-light-bordered-field-error-background-color         : rgba(lighten($mdlext-light-bordered-field-error-border-color, 50%), 0.5) !default;
+$mdlext-light-bordered-field-error-focus-border-color       : darken($mdlext-light-bordered-field-error-border-color, 10%) !default;
+$mdlext-light-bordered-field-error-focus-background-color   : $mdlext-light-bordered-field-error-background-color !default;
+
+$mdlext-light-bordered-field-input-text-label-color         : $mdlext-light-input-text-label-color !default;
+$mdlext-light-bordered-field-input-text-label-focus-color   : $mdlext-light-bordered-field-focus-border-color !default;
+$mdlext-light-bordered-field-input-text-label-error-color   : $mdlext-light-bordered-field-error-border-color !default;
+$mdlext-light-bordered-field-input-text-label-disabled-color: $mdlext-light-input-text-disabled-text-color !default;
+
+
+
+// ----------------------------------------------------------------
+// Dark Color Theme.
+// ----------------------------------------------------------------
+$mdlext-dark-color-primary:                       #FFC107 !default;
+$mdlext-dark-color-primary-dark:                  #FFA000 !default;
+$mdlext-dark-color-primary-light:                 #FFC107 !default;             // Fallback color. Set to color-primary if fallback is not needed
+$mdlext-dark-color-primary-contrast:              #FFF8E1 !default;             // text color on primary/primary dark background
+$mdlext-dark-color-accent:                        #536DFE !default;
+$mdlext-dark-color-accent-light:                  #536DFE !default;             // Fallback color. Set to color-accent if fallback is not needed
+$mdlext-dark-color-accent-contrast:               #FFFFFF !default;
+
+$mdlext-dark-content-background-color:            #303030 !default;             // #424242 or #303030, background color on content (paper/card) background
+$mdlext-dark-text-color-primary:                  rgba(#FFFFFF, 1.00) !default; // text color on content (paper/card) background
+$mdlext-dark-text-color-secondary:                rgba(#FFFFFF, 0.70) !default; // text color on content (paper/card) background
+$mdlext-dark-text-color-disabled:                 rgba(#FFFFFF, 0.50) !default; // disabled text, hint text, and icons
+$mdlext-dark-divider-color:                       rgba(#FFFFFF, 0.12) !default; // -> $card-border-color
+$mdlext-dark-error-color:                         #FF1744 !default;
+
+// Anchor
+$mdlext-dark-text-link-color:                     $mdlext-dark-color-accent !default;
+
+// Card
+$mdlext-dark-card-background-color:               $mdlext-dark-content-background-color !default;
+$mdlext-dark-card-text-color:                     $mdlext-dark-text-color-primary !default;
+$mdlext-dark-card-image-placeholder-color:        $mdlext-dark-color-accent !default;
+$mdlext-dark-card-supporting-text-text-color:     rgba($mdlext-color-white, 0.70) !default;
+$mdlext-dark-card-border-color:                   rgba(0, 0, 0, 0.1) !default;
+$mdlext-dark-card-subtitle-color:                 rgba($mdlext-color-black, 0.70) !default;
+
+//  Item
+
+// Default Item Colors
+$mdlext-dark-default-item-text-color:             rgba($mdlext-color-white, 0.87) !default;
+$mdlext-dark-default-item-outline-color:          $mdlext-palette-grey-700 !default;
+$mdlext-dark-default-item-hover-bg-color:         $mdlext-palette-grey-900 !default;
+$mdlext-dark-default-item-focus-bg-color:         $mdlext-palette-grey-900 !default;
+$mdlext-dark-default-item-active-bg-color:        $mdlext-palette-grey-800 !default;
+$mdlext-dark-default-item-divider-color:          rgba($mdlext-color-white, 0.20) !default;
+
+// Disabled Button Colors
+$mdlext-dark-disabled-item-text-color:            $mdlext-palette-grey-500 !default;
+
+// Dropdown menu / menu-button
+$mdlext-dark-default-dropdown-bg-color:           $mdlext-color-black !default;
+
+// Badge
+$mdlext-dark-badge-color:                         $mdlext-dark-color-accent-contrast !default;
+$mdlext-dark-badge-color-inverse:                 $mdlext-dark-color-accent !default;
+$mdlext-dark-badge-background:                    $mdlext-dark-color-accent !default;
+$mdlext-dark-badge-background-inverse:            $mdlext-dark-color-accent-contrast !default;
+
+// Default button colors.
+$mdlext-dark-button-primary-color:                rgba($mdlext-palette-grey-500, 0.20) !default;
+$mdlext-dark-button-secondary-color:              $mdlext-color-white !default;
+$mdlext-dark-button-hover-color:                  $mdlext-dark-button-primary-color !default;
+$mdlext-dark-button-active-color:                 rgba($mdlext-palette-grey-500, 0.40) !default;
+$mdlext-dark-button-focus-color:                  rgba($mdlext-color-black, 0.12) !default;
+
+// Colored button colors.
+$mdlext-dark-button-primary-color-alt:            $mdlext-dark-color-primary-light !default;
+$mdlext-dark-button-secondary-color-alt:          $mdlext-dark-color-primary-contrast !default;
+$mdlext-dark-button-hover-color-alt:              darken($mdlext-dark-color-primary-light, 10%) !default;
+$mdlext-dark-button-active-color-alt:             darken($mdlext-dark-color-primary-light, 10%) !default;
+$mdlext-dark-button-focus-color-alt:              $mdlext-dark-button-focus-color !default;
+
+// Ripple color for colored raised buttons.
+$mdlext-dark-button-ripple-color-alt:             $mdlext-dark-color-primary-contrast !default;
+
+// Disabled button colors.
+$mdlext-dark-button-primary-color-disabled:       rgba($mdlext-color-white, 0.12) !default;
+$mdlext-dark-button-secondary-color-disabled:     rgba($mdlext-color-white, 0.26) !default;
+
+// FAB colors and sizes.
+$mdlext-dark-button-fab-color-alt:                $mdlext-dark-color-accent !default;
+$mdlext-dark-button-fab-hover-color-alt:          $mdlext-dark-color-accent !default;
+$mdlext-dark-button-fab-active-color-alt:         $mdlext-dark-color-accent !default;
+$mdlext-dark-button-fab-text-color-alt:           $mdlext-dark-color-accent-contrast !default;
+$mdlext-dark-button-fab-ripple-color-alt:         $mdlext-dark-color-accent-contrast !default;
+
+// Slider
+$mdlext-dark-range-bg-color:                      rgba($mdlext-color-white, 0.87) !default;
+$mdlext-dark-range-color:                         $mdlext-dark-color-accent-light !default;
+$mdlext-dark-range-faded-color:                   rgba($mdlext-dark-color-accent-light, 0.50) !default;
+$mdlext-dark-range-bg-focus-color:                rgba($mdlext-color-white, 0.50) !default;
+
+// Textfields
+$mdlext-dark-input-text-background-color:         transparent !default;
+$mdlext-dark-input-text-label-color:              rgba($mdlext-color-white, 0.50) !default;
+$mdlext-dark-input-text-bottom-border-color:      rgba($mdlext-color-white, 0.26) !default;
+$mdlext-dark-input-text-highlight-color:          $mdlext-dark-color-accent-light !default;
+$mdlext-dark-input-text-disabled-color:           rgba($mdlext-color-white, 0.12) !default;
+$mdlext-dark-input-text-disabled-text-color:      rgba($mdlext-color-white, 0.26) !default;
+$mdlext-dark-input-text-error-color:              $mdlext-dark-error-color !default;
+
+// Checkboxes
+$mdlext-dark-checkbox-color:                      $mdlext-dark-color-accent-light !default;
+$mdlext-dark-checkbox-off-color:                  rgba($mdlext-color-white, 0.50) !default;
+$mdlext-dark-checkbox-disabled-color:             rgba($mdlext-color-white, 0.26) !default;
+$mdlext-dark-checkbox-focus-color:                rgba($mdlext-dark-color-accent-light, 0.26) !default;
+
+// Icon Toggles
+$mdlext-dark-icon-toggle-color:                   $mdlext-palette-grey-700 !default;
+$mdlext-dark-icon-toggle-focus-color:             $mdlext-dark-button-focus-color !default;
+$mdlext-dark-icon-toggle-checked-color:           $mdlext-dark-color-accent-light !default;
+$mdlext-dark-icon-toggle-checked-focus-color:     rgba($mdlext-dark-color-accent-light, 0.26) !default;
+$mdlext-dark-icon-toggle-disabled-color:          rgba($mdlext-color-white, 0.50) !default;
+
+// Radio Buttons
+$mdlext-dark-radio-color:                         $mdlext-dark-color-accent-light !default;
+$mdlext-dark-radio-off-color:                     rgba($mdlext-color-white, 0.50) !default;
+$mdlext-dark-radio-disabled-color:                rgba($mdlext-color-white, 0.26) !default;
+
+// Switches
+$mdlext-dark-switch-color:                        $mdlext-dark-color-accent-light !default;
+$mdlext-dark-switch-faded-color:                  rgba($mdlext-dark-color-accent-light, 0.26) !default;
+$mdlext-dark-switch-thumb-color:                  $mdlext-dark-switch-color !default;
+$mdlext-dark-switch-track-color:                  rgba($mdlext-dark-color-accent-light, 0.5) !default;
+$mdlext-dark-switch-off-thumb-color:              $mdlext-palette-grey-50 !default;
+$mdlext-dark-switch-off-track-color:              rgba($mdlext-color-white, 0.26) !default;
+$mdlext-dark-switch-disabled-thumb-color:         $mdlext-palette-grey-50 !default;
+$mdlext-dark-switch-disabled-track-color:         rgba($mdlext-color-white, 0.12) !default;
+
+// Data table
+$mdlext-dark-data-table-background-color:               $mdlext-dark-content-background-color !default;
+$mdlext-dark-data-table-header-color:                   rgba($mdlext-color-white, 0.87) !default;
+$mdlext-dark-data-table-header-sorted-color:            rgba($mdlext-color-white, 0.87) !default;
+$mdlext-dark-data-table-header-sorted-icon-hover-color: rgba($mdlext-color-white, 0.26) !default;
+$mdlext-dark-data-table-hover-color:                    $mdlext-dark-default-item-hover-bg-color !default;
+$mdlext-dark-data-table-selection-color:                $mdlext-dark-default-item-active-bg-color !default;
+$mdlext-dark-data-table-divider-color:                  rgba($mdlext-color-white, 0.12) !default;
+$mdlext-dark-data-table-dividers:                       1px solid $mdlext-dark-data-table-divider-color !default;
+
+
+// Selectfield
+// Uses variables from textfield
+
+
+// Accordion
+$mdlext-dark-accordion-header-background-color-base   : $mdlext-color-black !default;
+$mdlext-dark-accordion-header-background-color        : rgba($mdlext-dark-accordion-header-background-color-base, 1.0) !default;
+$mdlext-dark-accordion-header-background-open-color   : rgba($mdlext-dark-accordion-header-background-color-base, 0.9) !default;
+$mdlext-dark-accordion-header-border-color            : $mdlext-palette-grey-800 !default;
+$mdlext-dark-accordion-header-background-hover-color  : rgba($mdlext-dark-accordion-header-background-color-base, 0.5) !default;
+$mdlext-dark-accordion-header-background-active-color : rgba($mdlext-dark-accordion-header-background-color-base, 0.6) !default;
+$mdlext-dark-accordion-header-focus-outline-color     : lighten($mdlext-dark-accordion-header-border-color, 40%) !default;
+$mdlext-dark-accordion-header-disabled-color          : rgba($mdlext-dark-accordion-header-background-color-base, 0.4) !default;
+$mdlext-dark-accordion-header-secondary-color         : $mdlext-dark-text-color-primary !default;
+$mdlext-dark-accordion-header-secondary-color-disabled: $mdlext-dark-text-color-disabled !default;
+$mdlext-dark-accordion-header-highlight-color         : lighten($mdlext-dark-accordion-header-border-color, 40%) !default;
+$mdlext-dark-accordion-ripple-color                   : rgba($mdlext-dark-accordion-header-background-color-base, 0.3) !default;
+$mdlext-dark-accordion-content-color                  : inherit !default;
+$mdlext-dark-accordion-content-background-color       : transparent !default;
+
+
+// Bordered fields
+$mdlext-dark-bordered-field-input-text-color               : inherit !default;
+$mdlext-dark-bordered-field-border-color                   : $mdlext-dark-input-text-bottom-border-color !default;
+$mdlext-dark-bordered-field-background-color               : rgba($mdlext-dark-content-background-color, 0.1) !default;
+$mdlext-dark-bordered-field-focus-border-color             : $mdlext-dark-color-accent-light !default;
+$mdlext-dark-bordered-field-focus-background-color         : rgba(darken($mdlext-dark-bordered-field-background-color, 10%), 0.1) !default;
+
+$mdlext-dark-bordered-field-input-text-disabled-text-color : $mdlext-dark-input-text-disabled-text-color;
+$mdlext-dark-bordered-field-disabled-border-color          : $mdlext-dark-input-text-disabled-color !default;
+$mdlext-dark-bordered-field-disabled-background-color      : $mdlext-dark-bordered-field-background-color !default;
+
+$mdlext-dark-bordered-field-input-text-error-color         : $mdlext-dark-bordered-field-input-text-color !default;
+$mdlext-dark-bordered-field-error-border-color             : $mdlext-dark-input-text-error-color !default;
+$mdlext-dark-bordered-field-error-background-color         : rgba($mdlext-dark-bordered-field-error-border-color, 0.1) !default;
+$mdlext-dark-bordered-field-error-focus-border-color       : darken($mdlext-dark-bordered-field-error-border-color, 10%) !default;
+$mdlext-dark-bordered-field-error-focus-background-color   : $mdlext-dark-bordered-field-error-background-color !default;
+
+$mdlext-dark-bordered-field-input-text-label-color         : $mdlext-dark-input-text-label-color !default;
+$mdlext-dark-bordered-field-input-text-label-focus-color   : $mdlext-dark-bordered-field-focus-border-color !default;
+$mdlext-dark-bordered-field-input-text-label-error-color   : $mdlext-dark-bordered-field-error-border-color !default;
+$mdlext-dark-bordered-field-input-text-label-disabled-color: $mdlext-dark-input-text-disabled-text-color !default;
diff --git a/node_modules/mdl-ext/src/accordion/_accordion.scss b/node_modules/mdl-ext/src/accordion/_accordion.scss
new file mode 100644
index 0000000..6109194
--- /dev/null
+++ b/node_modules/mdl-ext/src/accordion/_accordion.scss
@@ -0,0 +1,395 @@
+@charset "UTF-8";
+
+/**
+ * @license
+ * Copyright 2016 Leif Olsen. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * This code is built with Google Material Design Lite,
+ * which is Licensed under the Apache License, Version 2.0
+ */
+
+.mdlext-aria-toggle-plus-minus {
+  @include mdlext-aria-expanded-toggle($font-family: inherit, $font-size: 1.4em);
+}
+
+.mdlext-aria-toggle-material-icons {
+  @include mdlext-aria-expanded-toggle($font-size: 1.3em, $icon: 'expand_more', $icon-expanded: 'expand_less', $icon-offset: -$mdlext-accordion-header-padding);
+}
+
+.mdlext-accordion {
+  box-sizing: border-box;
+  margin: 0;
+  padding: 0;
+  list-style: none;
+  display: flex;
+
+  * {
+    box-sizing: border-box;
+  }
+
+  &__panel {
+    box-sizing: border-box;
+    position: relative;
+    overflow: hidden;
+    display: flex;
+    flex-wrap: nowrap;
+  }
+
+  &__tab {
+    @include typo-title();
+
+    font-weight: 400;
+    line-height: 1.1;
+    box-sizing: border-box;
+    position: relative;
+    margin: 0;
+    padding: 0; // $mdlext-accordion-header-padding;
+    min-width: $mdlext-accordion-header-height;
+    min-height: $mdlext-accordion-header-height;
+    display: flex;
+    align-items: center;
+    align-self: stretch;
+    user-select: none;
+    color: $mdlext-accordion-header-secondary-color;
+    background-color: $mdlext-accordion-header-background-color;
+    cursor: pointer;
+    overflow: hidden;
+
+    &:focus {
+      outline-offset: -2px;
+      outline-color: $mdlext-accordion-header-focus-outline-color;
+      outline-width: 2px;
+    }
+
+    &[aria-expanded='true'] {
+      background-color: $mdlext-accordion-header-background-open-color;
+    }
+
+    &[aria-selected='true'] {
+      background-color: $mdlext-accordion-header-background-active-color;
+    }
+
+    &[disabled] {
+      background-color: $mdlext-accordion-header-disabled-color;
+      color: $mdlext-accordion-header-secondary-color-disabled;
+      pointer-events: none;
+
+      > * {
+        color: $mdlext-accordion-header-secondary-color-disabled;
+      }
+    }
+
+    &:hover:not([disabled]) {
+      background-color: $mdlext-accordion-header-background-hover-color;
+    }
+
+    > * {
+      margin: 0;
+      padding: 0;
+    }
+
+    &__caption {
+      padding-left: $mdlext-accordion-header-padding;
+      padding-right: $mdlext-accordion-header-padding;
+      white-space: nowrap;
+      overflow: hidden;
+      text-overflow: ellipsis;
+    }
+
+    > *:first-child {
+      padding-left: 0;
+    }
+
+    &--ripple {
+      &[aria-selected='true']::before {
+        content: '';
+        position: absolute;
+        top: 50%;
+        left: 50%;
+        background: $mdlext-accordion-ripple-color;
+        opacity: 0;
+        border-radius: 100%;
+        transform: scale(1, 1) translate(-50%);
+        transform-origin: 50% 50%;
+      }
+      &[aria-selected='true']:focus:not(:active)::before {
+        // http://easings.net/
+        animation: mdlext-accordion-tab-ripple 1s cubic-bezier(0.4, 0.0, 0.4, 1) 0.01s alternate forwards; // cubic-bezier(0.4, 0.0, 1, 1); //cubic-bezier(0.4, 0.0, 0.4, 1) 0.01s alternate forwards; //ease-out;
+      }
+    }
+  }
+
+  &__tabpanel {
+    box-sizing: border-box;
+    margin: 0;
+    padding: 0 $mdlext-accordion-content-padding;
+    color: $mdlext-accordion-content-color;
+    background-color: $mdlext-accordion-content-background-color;
+    display: block;
+    overflow: auto;
+    flex-grow: 1;
+
+    &[hidden] {
+      @include mdlext-visually-hidden;
+    }
+  }
+}
+
+// Vertical layout
+.mdlext-accordion {
+
+  &--vertical {
+    flex-direction: column;
+    flex-wrap: nowrap;
+
+    .mdlext-accordion__panel {
+      min-height: $mdlext-accordion-header-height;
+      flex-direction: column;
+    }
+
+    .mdlext-accordion__tab {
+      height: $mdlext-accordion-header-height;
+      border-top: 1px solid $mdlext-accordion-header-border-color;
+      padding-left: $mdlext-accordion-header-padding;
+      padding-right: $mdlext-accordion-header-padding;
+
+      &[aria-selected='true']::after {
+        position: absolute;
+        bottom: 0;
+        left: 0;
+        height: 1px;
+        width: 100%;
+        display: block;
+        content: " ";
+        background-color: $mdlext-accordion-header-highlight-color;
+        animation: border-expand 0.2s cubic-bezier(0.4, 0.0, 0.4, 1) 0.01s alternate forwards;
+        transition: all 1s cubic-bezier(0.4, 0.0, 1, 1);
+      }
+
+      > * {
+        padding-left: $mdlext-accordion-header-padding;
+      }
+
+      > *:first-child {
+        padding-left: 0;
+      }
+
+      > *:last-child:not(:only-child):not(.mdlext-accordion__tab__caption) {
+        margin-left: auto; // If more than one element, push last element to the right
+      }
+
+      &--ripple {
+        &[aria-selected='true']::before {
+          width: 5%;
+          height: 10%;
+        }
+      }
+
+    }
+
+    .mdlext-accordion__tabpanel {
+      border-top: 1px solid $mdlext-accordion-header-border-color;
+
+      &--animation {
+        transform: scaleY(1);
+        animation: mdlext-accordion-show-tabpanel-y 0.2s ease-in-out;
+
+        &[hidden] {
+          transform: scaleY(0);
+          animation: mdlext-accordion-hide-tabpanel-y 0.2s ease-out;
+          animation-delay: 0.1s;
+        }
+      }
+    }
+  }
+}
+
+// Horizontal layout
+.mdlext-accordion {
+
+  &--horizontal {
+
+    .mdlext-accordion__panel {
+      min-width: $mdlext-accordion-header-height;
+      width: $mdlext-accordion-header-height;
+    }
+
+    &[aria-multiselectable='true'] .mdlext-accordion__panel.is-expanded {
+      width: 100%;
+    }
+
+    .mdlext-accordion__tab {
+      flex-direction: column-reverse;
+      width: $mdlext-accordion-header-height;
+      white-space: nowrap;
+      border-left: 1px solid $mdlext-accordion-header-border-color;
+
+      &[aria-selected='true']::after {
+        position: absolute;
+        top: 0;
+        right: 0;
+        height: 100%;
+        width: 1px;
+        display: block;
+        content: " ";
+        background-color: $mdlext-accordion-header-highlight-color;
+
+        // Figure out how to animate a vertical line
+        //animation: border-expand 0.2s cubic-bezier(0.4, 0.0, 0.4, 1) 0.01s alternate forwards;
+        //transition: all 1s cubic-bezier(0.4, 0.0, 1, 1);
+      }
+
+      > * {
+        //transform: rotate(-90deg) translateX(50%);
+        transform: rotate(-90deg) translateX($mdlext-accordion-header-padding);
+      }
+
+      > *:last-child:not(:only-child):not(.mdlext-accordion__tab__caption) {
+        // If more than one element, push last element to top
+        margin-bottom: auto;
+        transform: rotate(-90deg) translateX(0);
+      }
+
+      &__caption {
+        transform: rotate(-90deg) translateX(50%);
+        padding-right: $mdlext-accordion-header-padding + 8px;
+      }
+
+      &--ripple {
+        &[aria-selected='true']::before {
+          width: 10%;
+          height: 5%;
+        }
+      }
+    }
+
+    .mdlext-accordion__tabpanel {
+      border-left: 1px solid $mdlext-accordion-header-border-color;
+
+      &--animation {
+        transform: scaleX(1);
+        animation: mdlext-accordion-show-tabpanel-x 0.2s ease-in-out;
+
+        &[hidden] {
+          transform: scaleX(0);
+          animation: mdlext-accordion-hide-tabpanel-x 0.2s ease-out;
+        }
+      }
+    }
+  }
+}
+
+.mdlext-accordion {
+
+  &__panel:first-child > &__tab {
+    // Use container to set outer borders
+    border-top-color: transparent;
+    border-left-color: transparent;
+  }
+
+  &[aria-multiselectable="false"] {
+    .mdlext-accordion__panel.is-expanded {
+      flex-grow: 1;
+    }
+  }
+}
+
+// Making accordion appear disabled.
+// Note: does not prevent tabbing into a disabled accordion
+.mdlext-accordion[disabled] {
+  * {
+    pointer-events: none;
+  }
+  .mdlext-accordion__tab {
+    background-color: $mdlext-accordion-header-disabled-color;
+    color: $mdlext-accordion-header-secondary-color-disabled;
+
+    > * {
+      color: $mdlext-accordion-header-secondary-color-disabled;
+    }
+  }
+  .mdlext-accordion__tabpanel {
+    opacity: 0.8;
+    filter: blur(1px) grayscale(80%);
+  }
+}
+
+
+@keyframes mdlext-accordion-tab-ripple {
+  0% {
+    transform: scale(0, 0);
+    opacity: 1;
+  }
+  20% {
+    transform: scale(25, 25);
+    opacity: 1;
+  }
+  100% {
+    opacity: 0;
+    transform: scale(40, 40);
+  }
+}
+
+/*
+@keyframes mdlext-accordion-show-tabpanel-y {
+  0% { transform: scaleY(0.1); }
+  40% { transform: scaleY(1.03); }
+  60% { transform: scaleY(0.98); }
+  80% { transform: scaleY(1.03); }
+  100% { transform: scaleY(0.98); }
+  80% { transform: scaleY(1.01); }
+  100% { transform: scaleY(1); }
+}
+*/
+
+@keyframes mdlext-accordion-show-tabpanel-y {
+  0% { transform: scaleY(0); }
+  60% { transform: scaleY(1.01); }
+  80% { transform: scaleY(0.98); }
+  100% { transform: scaleY(1); }
+}
+
+@keyframes mdlext-accordion-hide-tabpanel-y {
+  0% { transform: scaleY(1); }
+  60% { transform: scaleY(0.98); }
+  80% { transform: scaleY(1.01); }
+  100% { transform: scaleY(0); }
+}
+
+/*
+@keyframes mdlext-accordion-show-tabpanel-x {
+  0% { transform: scaleX(0.1); }
+  40% { transform: scaleX(1.03); }
+  60% { transform: scaleX(0.98); }
+  80% { transform: scaleX(1.03); }
+  100% { transform: scaleX(0.98); }
+  80% { transform: scaleX(1.01); }
+  100% { transform: scaleX(1); }
+}
+*/
+
+@keyframes mdlext-accordion-show-tabpanel-x {
+  0% { transform: scaleX(0); }
+  60% { transform: scaleX(1.01); }
+  80% { transform: scaleX(0.98); }
+  100% { transform: scaleX(1); }
+}
+
+@keyframes mdlext-accordion-hide-tabpanel-x {
+  0% { transform: scaleX(1); }
+  60% { transform: scaleX(0.98); }
+  80% { transform: scaleX(1.01); }
+  100% { transform: scaleX(0); }
+}
diff --git a/node_modules/mdl-ext/src/accordion/accordion.js b/node_modules/mdl-ext/src/accordion/accordion.js
new file mode 100644
index 0000000..0ef7bef
--- /dev/null
+++ b/node_modules/mdl-ext/src/accordion/accordion.js
@@ -0,0 +1,549 @@
+/**
+ * @license
+ * Copyright 2016 Leif Olsen. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * This code is built with Google Material Design Lite,
+ * which is Licensed under the Apache License, Version 2.0
+ */
+
+/**
+ * A WAI-ARIA friendly accordion component.
+ * An accordion is a collection of expandable panels associated with a common outer container. Panels consist
+ * of a header and an associated content region or tabpanel. The primary use of an Accordion is to present multiple sections
+ * of content on a single page without scrolling, where all of the sections are peers in the application or object hierarchy.
+ * The general look is similar to a tree where each root tree node is an expandable accordion header. The user navigates
+ * and makes the contents of each panel visible (or not) by interacting with the Accordion Header
+ */
+
+import {
+  VK_ENTER,
+  VK_SPACE,
+  VK_END,
+  VK_HOME,
+  VK_ARROW_LEFT,
+  VK_ARROW_UP,
+  VK_ARROW_RIGHT,
+  VK_ARROW_DOWN,
+  IS_EXPANDED,
+  IS_UPGRADED,
+  ARIA_MULTISELECTABLE,
+  ARIA_EXPANDED,
+  ARIA_HIDDEN,
+  ARIA_SELECTED
+} from '../utils/constants';
+
+
+(function() {
+  'use strict';
+  const ACCORDION            = 'mdlext-accordion';
+  const ACCORDION_VERTICAL   = 'mdlext-accordion--vertical';
+  const ACCORDION_HORIZONTAL = 'mdlext-accordion--horizontal';
+  const PANEL                = 'mdlext-accordion__panel';
+  const PANEL_ROLE           = 'presentation';
+  const TAB                  = 'mdlext-accordion__tab';
+  const TAB_CAPTION          = 'mdlext-accordion__tab__caption';
+  const TAB_ROLE             = 'tab';
+  const TABPANEL             = 'mdlext-accordion__tabpanel';
+  const TABPANEL_ROLE        = 'tabpanel';
+  const RIPPLE_EFFECT        = 'mdlext-js-ripple-effect';
+  const RIPPLE               = 'mdlext-accordion__tab--ripple';
+  const ANIMATION_EFFECT     = 'mdlext-js-animation-effect';
+  const ANIMATION            = 'mdlext-accordion__tabpanel--animation';
+
+  /**
+   * @constructor
+   * @param {Element} element The element that will be upgraded.
+   */
+  const MaterialExtAccordion = function MaterialExtAccordion( element ) {
+
+    // Stores the Accordion HTML element.
+    this.element_ = element;
+
+    // Initialize instance.
+    this.init();
+  };
+  window['MaterialExtAccordion'] = MaterialExtAccordion;
+
+
+  // Helpers
+  const accordionPanelElements = ( element ) => {
+    if(!element) {
+      return {
+        panel: null,
+        tab: null,
+        tabpanel: null
+      };
+    }
+    else if (element.classList.contains(PANEL)) {
+      return {
+        panel: element,
+        tab: element.querySelector(`.${TAB}`),
+        tabpanel: element.querySelector(`.${TABPANEL}`)
+      };
+    }
+    else {
+      return {
+        panel: element.parentNode,
+        tab: element.parentNode.querySelector(`.${TAB}`),
+        tabpanel: element.parentNode.querySelector(`.${TABPANEL}`)
+      };
+    }
+  };
+
+
+  // Private methods.
+
+  /**
+   * Handles custom command event, 'open', 'close', 'toggle' or upgrade
+   * @param event. A custom event
+   * @private
+   */
+  MaterialExtAccordion.prototype.commandHandler_ = function( event ) {
+    event.preventDefault();
+    event.stopPropagation();
+
+    if(event && event.detail) {
+      this.command(event.detail);
+    }
+  };
+
+  /**
+   * Dispatch toggle event
+   * @param {string} state
+   * @param {Element} tab
+   * @param {Element} tabpanel
+   * @private
+   */
+  MaterialExtAccordion.prototype.dispatchToggleEvent_ = function ( state, tab, tabpanel ) {
+    const ce = new CustomEvent('toggle', {
+      bubbles: true,
+      cancelable: true,
+      detail: { state: state, tab: tab, tabpanel: tabpanel }
+    });
+    this.element_.dispatchEvent(ce);
+  };
+
+  /**
+   * Open tab
+   * @param {Element} panel
+   * @param {Element} tab
+   * @param {Element} tabpanel
+   * @private
+   */
+  MaterialExtAccordion.prototype.openTab_ = function( panel, tab, tabpanel ) {
+    panel.classList.add(IS_EXPANDED);
+    tab.setAttribute(ARIA_EXPANDED, 'true');
+    tabpanel.removeAttribute('hidden');
+    tabpanel.setAttribute(ARIA_HIDDEN, 'false');
+    this.dispatchToggleEvent_('open', tab, tabpanel);
+  };
+
+  /**
+   * Close tab
+   * @param {Element} panel
+   * @param {Element} tab
+   * @param {Element} tabpanel
+   * @private
+   */
+  MaterialExtAccordion.prototype.closeTab_ = function( panel, tab, tabpanel ) {
+    panel.classList.remove(IS_EXPANDED);
+    tab.setAttribute(ARIA_EXPANDED, 'false');
+    tabpanel.setAttribute('hidden', '');
+    tabpanel.setAttribute(ARIA_HIDDEN, 'true');
+    this.dispatchToggleEvent_('close', tab, tabpanel);
+  };
+
+  /**
+   * Toggle tab
+   * @param {Element} panel
+   * @param {Element} tab
+   * @param {Element} tabpanel
+   * @private
+   */
+  MaterialExtAccordion.prototype.toggleTab_ = function( panel, tab, tabpanel ) {
+    if( !(this.element_.hasAttribute('disabled') || tab.hasAttribute('disabled')) ) {
+      if (tab.getAttribute(ARIA_EXPANDED).toLowerCase() === 'true') {
+        this.closeTab_(panel, tab, tabpanel);
+      }
+      else {
+        if (this.element_.getAttribute(ARIA_MULTISELECTABLE).toLowerCase() !== 'true') {
+          this.closeTabs_();
+        }
+        this.openTab_(panel, tab, tabpanel);
+      }
+    }
+  };
+
+  /**
+   * Open tabs
+   * @private
+   */
+  MaterialExtAccordion.prototype.openTabs_ = function() {
+    if (this.element_.getAttribute(ARIA_MULTISELECTABLE).toLowerCase() === 'true') {
+      [...this.element_.querySelectorAll(`.${ACCORDION} > .${PANEL}`)]
+        .filter(panel => !panel.classList.contains(IS_EXPANDED))
+        .forEach(closedItem => {
+          const tab = closedItem.querySelector(`.${TAB}`);
+          if (!tab.hasAttribute('disabled')) {
+            this.openTab_(closedItem, tab, closedItem.querySelector(`.${TABPANEL}`));
+          }
+        });
+    }
+  };
+
+  /**
+   * Close tabs
+   * @private
+   */
+  MaterialExtAccordion.prototype.closeTabs_ = function() {
+    [...this.element_.querySelectorAll(`.${ACCORDION} > .${PANEL}.${IS_EXPANDED}`)]
+      .forEach( panel => {
+        const tab = panel.querySelector(`.${TAB}`);
+        if(!tab.hasAttribute('disabled')) {
+          this.closeTab_(panel, tab, panel.querySelector(`.${TABPANEL}`));
+        }
+      });
+  };
+
+
+  // Public methods.
+
+  /**
+   * Upgrade an individual accordion tab
+   * @public
+   * @param {Element} tabElement The HTML element for the accordion panel.
+   */
+  MaterialExtAccordion.prototype.upgradeTab = function( tabElement ) {
+
+    const { panel, tab, tabpanel } = accordionPanelElements( tabElement );
+
+    const disableTab = () => {
+      panel.classList.remove(IS_EXPANDED);
+      tab.setAttribute('tabindex', '-1');
+      tab.setAttribute(ARIA_EXPANDED, 'false');
+      tabpanel.setAttribute('hidden', '');
+      tabpanel.setAttribute(ARIA_HIDDEN, 'true');
+    };
+
+    const enableTab = () => {
+      if(!tab.hasAttribute(ARIA_EXPANDED)) {
+        tab.setAttribute(ARIA_EXPANDED, 'false');
+      }
+
+      tab.setAttribute('tabindex', '0');
+
+      if(tab.getAttribute(ARIA_EXPANDED).toLowerCase() === 'true') {
+        panel.classList.add(IS_EXPANDED);
+        tabpanel.removeAttribute('hidden');
+        tabpanel.setAttribute(ARIA_HIDDEN, 'false');
+      }
+      else {
+        panel.classList.remove(IS_EXPANDED);
+        tabpanel.setAttribute('hidden', '');
+        tabpanel.setAttribute(ARIA_HIDDEN, 'true');
+      }
+    };
+
+    // In horizontal layout, caption must have a max-width defined to prevent pushing elements to the right of the caption out of view.
+    // In JsDom, offsetWidth and offsetHeight properties do not work, so this function is not testable.
+    /* istanbul ignore next */
+    const calcMaxTabCaptionWidth = () => {
+
+      const tabCaption = tab.querySelector(`.${TAB_CAPTION}`);
+      if(tabCaption !== null) {
+        const w = [...tab.children]
+          .filter( el => el.classList && !el.classList.contains(TAB_CAPTION) )
+          .reduce( (v, el) => v + el.offsetWidth, 0 );
+
+        const maxWidth = tab.clientHeight - w;
+        if(maxWidth > 0) {
+          tabCaption.style['max-width'] = `${maxWidth}px`;
+        }
+      }
+    };
+
+    const selectTab = () => {
+      if( !tab.hasAttribute(ARIA_SELECTED) ) {
+        [...this.element_.querySelectorAll(`.${TAB}[aria-selected="true"]`)].forEach(
+          selectedTab => selectedTab.removeAttribute(ARIA_SELECTED)
+        );
+        tab.setAttribute(ARIA_SELECTED, 'true');
+      }
+    };
+
+    const tabClickHandler = () => {
+      this.toggleTab_(panel, tab, tabpanel);
+      selectTab();
+    };
+
+    const tabFocusHandler = () => {
+      selectTab();
+    };
+
+    const tabpanelClickHandler = () => {
+      selectTab();
+    };
+
+    const tabpanelFocusHandler = () => {
+      selectTab();
+    };
+
+    const tabKeydownHandler = e => {
+
+      if(this.element_.hasAttribute('disabled')) {
+        return;
+      }
+
+      if ( e.keyCode === VK_END        || e.keyCode === VK_HOME
+        || e.keyCode === VK_ARROW_UP   || e.keyCode === VK_ARROW_LEFT
+        || e.keyCode === VK_ARROW_DOWN || e.keyCode === VK_ARROW_RIGHT ) {
+
+        let nextTab = null;
+        let keyCode = e.keyCode;
+
+        if (keyCode === VK_HOME) {
+          nextTab = this.element_.querySelector(`.${PANEL}:first-child > .${TAB}`);
+          if(nextTab && nextTab.hasAttribute('disabled')) {
+            nextTab = null;
+            keyCode = VK_ARROW_DOWN;
+          }
+        }
+        else if (keyCode === VK_END) {
+          nextTab = this.element_.querySelector(`.${PANEL}:last-child > .${TAB}`);
+          if(nextTab && nextTab.hasAttribute('disabled')) {
+            nextTab = null;
+            keyCode = VK_ARROW_UP;
+          }
+        }
+
+        if(!nextTab) {
+          let nextPanel = panel;
+
+          do {
+            if (keyCode === VK_ARROW_UP || keyCode === VK_ARROW_LEFT) {
+              nextPanel = nextPanel.previousElementSibling;
+              if(!nextPanel) {
+                nextPanel = this.element_.querySelector(`.${PANEL}:last-child`);
+              }
+              if (nextPanel) {
+                nextTab = nextPanel.querySelector(`.${PANEL} > .${TAB}`);
+              }
+            }
+            else if (keyCode === VK_ARROW_DOWN || keyCode === VK_ARROW_RIGHT) {
+              nextPanel = nextPanel.nextElementSibling;
+              if(!nextPanel) {
+                nextPanel = this.element_.querySelector(`.${PANEL}:first-child`);
+              }
+              if (nextPanel) {
+                nextTab = nextPanel.querySelector(`.${PANEL} > .${TAB}`);
+              }
+            }
+
+            if(nextTab && nextTab.hasAttribute('disabled')) {
+              nextTab = null;
+            }
+            else {
+              break;
+            }
+          }
+          while(nextPanel !== panel);
+        }
+
+        if (nextTab) {
+          e.preventDefault();
+          e.stopPropagation();
+          nextTab.focus();
+
+          // Workaround for JSDom testing:
+          // In JsDom 'element.focus()' does not trigger any focus event
+          if(!nextTab.hasAttribute(ARIA_SELECTED)) {
+
+            [...this.element_.querySelectorAll(`.${TAB}[aria-selected="true"]`)]
+              .forEach( selectedTab => selectedTab.removeAttribute(ARIA_SELECTED) );
+
+            nextTab.setAttribute(ARIA_SELECTED, 'true');
+          }
+        }
+      }
+      else if (e.keyCode === VK_ENTER || e.keyCode === VK_SPACE) {
+        e.preventDefault();
+        e.stopPropagation();
+        this.toggleTab_(panel, tab, tabpanel);
+      }
+    };
+
+    if(tab === null) {
+      throw new Error('There must be a tab element for each accordion panel.');
+    }
+
+    if(tabpanel === null) {
+      throw new Error('There must be a tabpanel element for each accordion panel.');
+    }
+
+    panel.setAttribute('role', PANEL_ROLE);
+    tab.setAttribute('role', TAB_ROLE);
+    tabpanel.setAttribute('role', TABPANEL_ROLE);
+
+    if(tab.hasAttribute('disabled')) {
+      disableTab();
+    }
+    else {
+      enableTab();
+    }
+
+    if( this.element_.classList.contains(ACCORDION_HORIZONTAL)) {
+      calcMaxTabCaptionWidth();
+    }
+
+    if (this.element_.classList.contains(RIPPLE_EFFECT)) {
+      tab.classList.add(RIPPLE);
+    }
+
+    if (this.element_.classList.contains(ANIMATION_EFFECT)) {
+      tabpanel.classList.add(ANIMATION);
+    }
+
+    // Remove listeners, just in case ...
+    tab.removeEventListener('click', tabClickHandler);
+    tab.removeEventListener('focus', tabFocusHandler);
+    tab.removeEventListener('keydown', tabKeydownHandler);
+    tabpanel.removeEventListener('click', tabpanelClickHandler);
+    tabpanel.removeEventListener('focus', tabpanelFocusHandler);
+
+    tab.addEventListener('click', tabClickHandler);
+    tab.addEventListener('focus', tabFocusHandler);
+    tab.addEventListener('keydown', tabKeydownHandler);
+    tabpanel.addEventListener('click', tabpanelClickHandler, true);
+    tabpanel.addEventListener('focus', tabpanelFocusHandler, true);
+  };
+  MaterialExtAccordion.prototype['upgradeTab'] = MaterialExtAccordion.prototype.upgradeTab;
+
+
+  /**
+   * Execute command
+   * @param detail
+   */
+  MaterialExtAccordion.prototype.command = function( detail ) {
+
+    const openTab = tabElement => {
+
+      if(tabElement === undefined) {
+        this.openTabs_();
+      }
+      else if(tabElement !== null) {
+        const { panel, tab, tabpanel } = accordionPanelElements( tabElement );
+        if(tab.getAttribute(ARIA_EXPANDED).toLowerCase() !== 'true') {
+          this.toggleTab_(panel, tab, tabpanel);
+        }
+      }
+    };
+
+    const closeTab = tabElement => {
+      if(tabElement === undefined) {
+        this.closeTabs_();
+      }
+      else if(tabElement !== null) {
+        const { panel, tab, tabpanel } = accordionPanelElements( tabElement );
+
+        if(tab.getAttribute(ARIA_EXPANDED).toLowerCase() === 'true') {
+          this.toggleTab_(panel, tab, tabpanel);
+        }
+      }
+    };
+
+    const toggleTab = tabElement => {
+      if(tabElement) {
+        const { panel, tab, tabpanel } = accordionPanelElements( tabElement );
+        this.toggleTab_(panel, tab, tabpanel);
+      }
+    };
+
+
+    if(detail && detail.action) {
+      const { action, target } = detail;
+
+      switch (action.toLowerCase()) {
+        case 'open':
+          openTab(target);
+          break;
+        case 'close':
+          closeTab(target);
+          break;
+        case 'toggle':
+          toggleTab(target);
+          break;
+        case 'upgrade':
+          if(target) {
+            this.upgradeTab(target);
+          }
+          break;
+        default:
+          throw new Error(`Unknown action "${action}". Action must be one of "open", "close", "toggle" or "upgrade"`);
+      }
+    }
+  };
+  MaterialExtAccordion.prototype['command'] = MaterialExtAccordion.prototype.command;
+
+
+  /**
+   * Initialize component
+   */
+  MaterialExtAccordion.prototype.init = function() {
+    if (this.element_) {
+      // Do the init required for this component to work
+      if( !(this.element_.classList.contains(ACCORDION_HORIZONTAL) || this.element_.classList.contains(ACCORDION_VERTICAL))) {
+        throw new Error(`Accordion must have one of the classes "${ACCORDION_HORIZONTAL}" or "${ACCORDION_VERTICAL}"`);
+      }
+
+      this.element_.setAttribute('role', 'tablist');
+
+      if(!this.element_.hasAttribute(ARIA_MULTISELECTABLE)) {
+        this.element_.setAttribute(ARIA_MULTISELECTABLE, 'false');
+      }
+
+      this.element_.removeEventListener('command', this.commandHandler_);
+      this.element_.addEventListener('command', this.commandHandler_.bind(this), false);
+
+      [...this.element_.querySelectorAll(`.${ACCORDION} > .${PANEL}`)].forEach( panel => this.upgradeTab(panel) );
+
+      // Set upgraded flag
+      this.element_.classList.add(IS_UPGRADED);
+    }
+  };
+
+
+  /*
+   * Downgrade component
+   * E.g remove listeners and clean up resources
+   *
+   * Nothing to downgrade
+   *
+   MaterialExtAccordion.prototype.mdlDowngrade_ = function() {
+     'use strict';
+     console.log('***** MaterialExtAccordion.mdlDowngrade');
+   };
+   */
+
+
+  // The component registers itself. It can assume componentHandler is available
+  // in the global scope.
+  /* eslint no-undef: 0 */
+  componentHandler.register({
+    constructor: MaterialExtAccordion,
+    classAsString: 'MaterialExtAccordion',
+    cssClass: 'mdlext-js-accordion',
+    widget: true
+  });
+})();
diff --git a/node_modules/mdl-ext/src/accordion/readme.md b/node_modules/mdl-ext/src/accordion/readme.md
new file mode 100644
index 0000000..e8ddd3a
--- /dev/null
+++ b/node_modules/mdl-ext/src/accordion/readme.md
@@ -0,0 +1,384 @@
+# Accordion
+![Accordion](../../etc/flexbox-accordion.png)
+
+A WAI-ARIA friendly accordion component.
+
+>**Note:** The accordion has been refactored and is not compatible with accordion prior to version 0.9.13
+
+## Introduction
+An accordion component is a collection of expandable panels associated with a common outer container. Panels consist
+of a tab header and an associated content region or panel. The primary use of an Accordion is to present multiple sections
+of content on a single page without scrolling, where all of the sections are peers in the application or object hierarchy.
+The general look is similar to a tree where each root tree node is an expandable accordion header. The user navigates
+and makes the contents of each panel visible (or not) by interacting with the Accordion tab header.
+
+### Features:
+* The accordion component relates to the guidelines given in [WAI-ARIA Authoring Practices 1.1, Accordion](https://www.w3.org/TR/wai-aria-practices-1.1/#accordion) 
+* User interactions via keyboard or mouse 
+* Toggle a particular tab  using enter or space key, or by clicking a tab
+* Client can interact with accordion using a public api og by dispatching a custom action event 
+* The accordion emits a custom toggle events reflecting the tab toggled
+
+
+### To include a MDLEXT **accordion** component:
+
+&nbsp;1. Code a `<ul>` element with `class="mdlext-accordion mdlext-js-accordion mdlext-accordion--horizontal"`  to hold the accordion with horizontal layout. 
+```html
+<ul class="mdlext-accordion mdlext-js-accordion mdlext-accordion--horizontal">
+</ul>
+```
+
+&nbsp;2. Code a `<li>` element with `class="mdlext-accordion__panel"`  to hold an individual accordion panel. 
+```html
+<ul class="mdlext-accordion mdlext-js-accordion mdlext-accordion--horizontal">
+  <li class="mdlext-accordion__panel">
+  </li>
+</ul>
+```
+
+&nbsp;3. Code a `<header>` element with `class="mdlext-accordion__tab"`  to hold the accordion tab header. 
+```html
+<ul class="mdlext-accordion mdlext-js-accordion mdlext-accordion--horizontal">
+  <li class="mdlext-accordion__panel">
+    <header class="mdlext-accordion__tab">
+    </header>
+  </li>
+</ul>
+```
+
+&nbsp;4. Code a `<span>` element with `class="mdlext-accordion__tab__caption"` to hold the accordion tab header caption. 
+```html
+<ul class="mdlext-accordion mdlext-js-accordion mdlext-accordion--horizontal">
+  <li class="mdlext-accordion__panel">
+    <header class="mdlext-accordion__tab">
+      <span class="mdlext-accordion__tab__caption">A tab caption</span>
+    </header>
+  </li>
+</ul>
+```
+
+&nbsp;5. Code a `<section>` element with `class="mdlext-accordion__tabpanel"`  to hold the tab content. 
+```html
+<ul class="mdlext-accordion mdlext-js-accordion mdlext-accordion--horizontal">
+  <li class="mdlext-accordion__panel">
+    <header class="mdlext-accordion__tab">
+      <span class="mdlext-accordion__tab__caption">A tab caption</span>
+    </header>
+    <section class="mdlext-accordion__tabpanel">
+      <p>Content goes here ...</p>
+    </section>
+  </li>
+</ul>
+```
+
+&nbsp;6. Repeat steps 2..5 for each accordion panel required. 
+
+### Example
+Multiselectable vertical accordion with three panels, aria attributes, ripple effect on each tab header, decorated with 
+a glyph left and a state icon right. Tab #1 is open at page load (aria-expanded="true"). Subscribes to accordion toggle event.
+
+```html
+<ul id="my-accordion" 
+  class="mdlext-accordion mdlext-js-accordion mdlext-accordion--vertical mdlext-js-ripple-effect"
+  role="tablist" aria-multiselectable="true">
+
+  <li class="mdlext-accordion__panel" role="presentation">
+    <header class="mdlext-accordion__tab" role="tab" aria-expanded="true">
+      <i class="material-icons">dns</i>
+      <span class="mdlext-accordion__tab__caption">First section. A long caption should not push the state icon</span>
+      <i class="mdlext-aria-toggle-material-icons"></i>
+    </header>
+    <section class="mdlext-accordion__tabpanel" role="tabpanel" aria-hidden="false">
+      <h5>Content #1 goes here</h5>
+      <p>Some content <a href="#">with an anchor</a> as a focusable element.</p>
+    </section>
+  </li>
+  <li class="mdlext-accordion__panel" role="presentation">
+    <header class="mdlext-accordion__tab" role="tab" aria-expanded="false">
+      <i class="material-icons">all_inclusive</i>
+      <span class="mdlext-accordion__tab__caption">Tab #2</span>
+      <i class="mdlext-aria-toggle-material-icons"></i>
+    </header>
+    <section class="mdlext-accordion__tabpanel" role="tabpanel" aria-hidden="true" hidden>
+      <h5>Content #2 goes here</h5>
+      <p>Some content....</p>
+    </section>
+  </li>
+  <li class="mdlext-accordion__panel" role="presentation">
+    <header class="mdlext-accordion__tab" role="tab" aria-expanded="false">
+      <i class="material-icons">build</i>
+      <span class="mdlext-accordion__tab__caption">Tab #3</span>
+      <i class="mdlext-aria-toggle-material-icons"></i>
+    </header>
+    <section class="mdlext-accordion__tabpanel" role="tabpanel" aria-hidden="true" hidden>
+      <h5>Content #3 goes here</h5>
+    </section>
+  </li>
+</ul>
+
+<script>
+  'use strict';
+  window.addEventListener('load', function() {
+    var accordion = document.querySelector('#my-accordion');
+    accordion.addEventListener('toggle', function(e) {
+      console.log('Accordion toggled. State:', e.detail.state, 'Source:', e.detail.tab);
+    });
+  });
+</script>
+
+```
+>**Note:** All required aria attributes will be added by the accordion component during initialization - so it is not 
+strictly necessary to apply the attributes in markup.
+
+### More examples
+* The [snippets/accordion.html](./snippets/accordion.html) and the [tests](../../test/accordion/accordion.spec.js) provides more detailed examples.
+* Try out the [live demo](http://leifoolsen.github.io/mdl-ext/demo/accordion.html)
+
+
+## Keyboard interaction
+The accordion interacts with the following keyboard keys.
+
+*   <kbd>Tab</kbd> - When focus is on an accordion (tab)header, pressing the <kbd>Tab</kbd> key moves focus in the following manner:
+    1.  If interactive glyphs or menus are present in the accordion header, focus moves to each in order.
+    2.  When the corresponding tab panel is expanded (its [aria-expanded](http://www.w3.org/TR/wai-aria-1.1/#aria-expanded) state is 'true'), then focus moves to the first focusable element in the panel.
+    3.  If the panel is collapsed (its aria-expanded state is 'false'), OR, when the last interactive element of a panel is reached, the next <kbd>Tab</kbd> key press moves focus as follows:
+        *   Moves focus to the next logical accordion header.
+        *   When focus reaches the last header, focus moves to the first focusable element outside the accordion component.
+*   <kbd>Left arrow</kbd>
+    *   When focus is on the accordion header, a press of <kbd>up</kbd>/<kbd>left</kbd> arrow keys moves focus to the previous logical accordion header.
+    *   When focus reaches the first header, further <kbd>up</kbd>/<kbd>left</kbd> arrow key presses optionally wrap to the first header.
+*   <kbd>Right arrow</kbd>
+    *   When focus is on the accordion header, a press of <kbd>down</kbd>/<kbd>right</kbd> arrow key moves focus to the next logical accordion header.
+    *   When focus reaches the last header, further <kbd>down</kbd>/<kbd>right</kbd> arrow key presses optionally wrap to the first header
+*   <kbd>Up arrow</kbd> - behaves the same as left arrow
+*   <kbd>Down arrow</kbd> - behaves the same as <kbd>right arrow</kbd>
+*   <kbd>End</kbd> - When focus is on the accordion header, an <kbd>End</kbd> key press moves focus to the last accordion header.
+*   <kbd>Home</kbd> - When focus is on the accordion header, a <kbd>Home</kbd> key press moves focus to the first accordion header.
+*   <kbd>Enter</kbd> or <kbd>Space</kbd> - When focus is on an accordion header, pressing <kbd>Enter</kbd> ir <kbd>Space</kbd> toggles the expansion of the corresponding panel.
+    *   If collapsed, the panel is expanded, and its aria-expanded state is set to 'true'.
+    *   If expanded, the panel is collapsed and its aria-expanded state is set to 'false'.
+*   <kbd>Shift+Tab</kbd> - Generally the reverse of <kbd>Tab</kbd>.
+
+
+## Events
+Interaction with the component programmatically is performed receiving events from the component or by sending events to 
+the component (or by using the public api).  
+
+### Events the component listenes to
+A client can send a `command` custom event to the accordion. The command event holds a detail object defining the action 
+to perform and a target for the action.
+
+The detail object has the following structure:
+```javascript
+detail: { 
+  action, // "open", "close", "toggle" or "upgrade" 
+  target  // Target, panel or tab, of action, "undefined" if all panels should be targeted.
+          // Note: If you send a null target, the action is cancelled
+}
+```
+
+Possible actions are:
+
+#### open
+Open a targeted tab and it's corresponding tabpanel.
+
+```javascript
+myAccrdion = document.querySelector('#my-accordion');
+target = myAccordion.querySelector('#my-accordion .mdlext-accordion__panel:nth-child(3)'); 
+ce = new CustomEvent('command', { detail: { action : 'open', target: target } });
+```
+If `target` is undefined, the action will open all panels.
+**Note**: Opening all panels only makes sense if the accordion has the aria attribute `aria-multiselectable` set to `true`, 
+and will be cancelled otherwise. 
+
+#### close
+Close a targeted tab and its corresponding tabpanel.
+
+```javascript
+myAccrdion = document.querySelector('#my-accordion');
+target = myAccordion.querySelector('#my-accordion .mdlext-accordion__panel:nth-child(3)'); 
+ce = new CustomEvent('command', { detail: { action : 'close', target: target } });
+```
+If `target` is undefined, the action will close all panels.
+**Note**: Closing all panels only makes sense if the accordion has the aria attribute `aria-multiselectable` set to `true`, 
+and will be cancelled otherwise. 
+
+#### toggle
+Toggle a targeted tab. Open or close a targeted tab and it's corresponding tabpanel.
+
+```javascript
+myAccrdion = document.querySelector('#my-accordion');
+target = myAccordion.querySelector('#my-accordion .mdlext-accordion__panel:nth-child(3)'); 
+ce = new CustomEvent('command', { detail: { action : 'toggle', target: target } });
+```
+If `target` is undefined, the action will be cancelled.
+
+#### upgrade
+Upgrade a targeted panel. If you add a panel to the accordion after the page has loaded, you must call `upgrade` to 
+notify the accordion component about the new panel.
+
+```javascript
+myAccrdion = document.querySelector('#my-accordion');
+addedPanel = myAccordion.querySelector('#my-accordion .mdlext-accordion__panel:nth-child(4)'); 
+ce = new CustomEvent('command', { detail: { action : 'upgrade', target: addedPanel } });
+```
+If `target` is undefined, the action will be cancelled.
+
+#### Example: Expand all panels.
+```javascript
+var ce = new CustomEvent( 'command', { 
+  detail: { 
+    action: 'open' 
+  } 
+});
+document.querySelector('#my-accordion').dispatchEvent(ce);
+```
+
+#### Example: Toggle a spesific tab.
+```javascript
+var panel3 = document.querySelector('#my-accordion .mdlext-accordion__panel:nth-child(3) .mdlext-accordion__tab');
+var ce = new CustomEvent('command', { 
+  detail: { 
+    action: 'toggle', 
+    target: panel3 
+  } 
+});
+document.querySelector('#my-accordion').dispatchEvent(ce);
+```
+
+#### Example: Append a new panel.
+```javascript
+var panel =
+  '<li class="mdlext-accordion__panel">'
+  +  '<header class="mdlext-accordion__tab" aria-expanded="true">'
+  +    '<span class="mdlext-accordion__tab__caption">New Tab</span>'
+  +    '<i class="mdlext-aria-toggle-material-icons"></i>'
+  +  '</header>'
+  +  '<section class="mdlext-accordion__tabpanel">'
+  +    '<h5>New tab content</h5>'
+  +    '<p>Some content</p>'
+  +  '</section>'
+  +'</li>';
+
+var accordion = document.querySelector('#my-accordion');
+accordion.insertAdjacentHTML('beforeend', panel);
+
+var theNewPanel = document.querySelector('#my-accordion .mdlext-accordion__panel:last-child');
+var ce = new CustomEvent('command', { detail: { action : 'upgrade', target: theNewPanel } });
+document.querySelector('#my-accordion').dispatchEvent(ce);
+```
+
+Refer to [snippets/accordion.html](./snippets/accordion.html) or the [tests](../../test/accordion/accordion.spec.js) for detailed usage.
+
+
+### Events emitted from the component
+The accordion emits a custom `toggle` event when a panel opens or closes. The event has a detail object with the following structure:
+
+```javascript
+detail: {
+  state,    // "open" or "close"
+  tab,      // the haeder tab element instance that caused the event
+  tabpanel  // the cooresponding tabpanel element instance
+}
+```
+
+Set up an event listener to receive the toggle event.
+```javascript
+document.querySelector('#my-accordion').addEventListener('toggle', function(e) {
+  console.log('Accordion toggled. State:', e.detail.state, 'Source:', e.detail.source);
+});
+```
+Refer to [snippets/accordion.html](./snippets/accordion.html) or the [tests](../../test/accordion/accordion.spec.js) for detailed usage.
+
+
+## Public methods
+
+### upgradeTab(tabOrPanelElement)
+Upgrade a targeted panel with aria attributes and ripple effects. If you add a panel to the accordion after the page has 
+loaded, you must call `upgrade` to notify the accordion component about the newly added panel.
+
+```javascript
+var accordion = document.querySelector('#my-accordion');
+var panel3 = document.querySelector('#my-accordion .mdlext-accordion__panel:nth-child(3)');
+accordion.MaterialExtAccordion.upgradeTab( panel3 );
+```
+
+### command(detail)
+Executes an action, targeting a specific tab. The actions corresponds to the custom events defined for this component.
+ 
+The detail object parameter has the following structure:
+```javascript
+detail: { 
+  action, // "open", "close", "toggle" or "upgrade" 
+  target  // Target, panel or tab, of action, "undefined" if all panels should be targeted.
+          // Note: If you send a null target, the action is cancelled
+}
+```
+
+#### open: command( {action: 'open', target: tabOrPanelElement } )
+Open a targeted tab and it's corresponding tabpanel.
+
+#### close: command( {action: 'close', target: tabOrPanelElement } )
+Close a targeted tab and it's corresponding tabpanel.
+
+#### toggle: command( {action: 'toggle', target: tabOrPanelElement } )
+Toggle a targeted tab. Open or close a targeted tab and it's corresponding tabpanel.
+
+#### upgrade: command( {action: 'upgrade', target: tabOrPanelElement } )
+Upgrade a targeted panel with aria attributes and ripple effects. If you add a panel to the accordion after the page has 
+loaded, you must call `upgrade` to notify the accordion component about the newly added panel.
+
+#### Example: Expand all panels.
+```javascript
+var accordion = document.querySelector('#my-accordion');
+accordion.MaterialExtAccordion.command( {action: 'open'} );
+```
+
+#### Example: Toggle panel.
+```javascript
+var accordion = document.querySelector('#my-accordion');
+var panel3 = document.querySelector('#my-accordion .mdlext-accordion__panel:nth-child(3) .mdlext-accordion__tab');
+accordion.MaterialExtAccordion.command( {action: 'toggle', target: panel3} );
+```
+
+Refer to [snippets/accordion.html](./snippets/accordion.html) or the [tests](../../test/accordion/accordion.spec.js) for detailed usage.
+
+
+## Configuration options
+
+The MDLEXT CSS classes apply various predefined visual and behavioral enhancements to the accordion. 
+The table below lists the available classes and their effects.
+
+| MDLEXT class | Effect | Remarks |
+|--------------|--------|---------|
+|`mdlext-accordion`| Defines container as an MDL component | Required on "outer" `<div>` or `<ul>` element |
+|`mdlext-js-accordion`| Assigns basic MDL behavior to accordion | Required on "outer" `<div>` or `<ul>` element |
+|`mdlext-accordion--horizontal`| Horizontal layot of an accordion | Required. The accordion must have one of `mdlext-accordion--horizontal` or `mdlext-accordion--vertical` defined |
+|`mdlext-accordion--vertical`| Vertical layot of an accordion | Required. The accordion must have one of `mdlext-accordion--horizontal` or `mdlext-accordion--vertical` defined |
+|`mdlext-js-ripple-effect`| Applies ripple click effect to accordion tab header | Optional. Goes on "outer" `<ul>` or `<div>` element |
+|`mdlext-js-animation-effect`| Applies animation effect to accordion tab panel | Optional. Goes on "outer" `<ul>` or `<div>` element |
+|`mdlext-accordion__panel`| Defines a container for each section of the accordion - the tab and tabpanel element | Required on first inner `<div>` element or `<li>` element  |
+|`mdlext-accordion__tab`| Defines a tab header for a corresponding tabpanel | Required on `<header>` or `<div>` element |
+|`mdlext-accordion__tabpanel`| The content | Required on `<section>` or `<div>` element |
+
+
+The table below lists available attributes and their effects.
+
+| Attribute | Description | Remarks |
+|-----------|-------------|---------|
+|`aria-multiselectable`| If true, multiple panels may be open simultaneously | Required. Add `aria-multiselectable="true"` to the `mdlext-accordion` element to keep multiple panels open at the same time. If not present, the component will set `aria-multiselectable="false"` during initialization.|
+|`role=tablist`| Component role | Required. Added by component during initialization if not present. |
+|`role=presentation`| Accordion panel role | Required. Added by component during initialization if not present. |
+|`role=tab`| Accordion tab header role | Required. Added by component during initialization if not present. |
+|`aria-expanded`| Accordion tab header attribute.  An accordion should manage the expanded/collapsed state of each tab by maintain its aria-expanded state. | Required. Defaults to `aria-expanded="false"`. Set `aria-expanded="true"` if you want a tab to open during page load. |
+|`aria-selected`| Accordion tab header attribute. An accordion should manage the selected state of each tab by maintaining its aria-selected state | Optional. Added by component. |
+|`disabled`| Accordion tab header attribute. Indicates a disabled tab and tabpanel | Optional. If this attribute is present, the tabpanel will not open or close. |
+|`role=tabpanel`| Accordion tabpanel role. | Required. Added by component during initialization if not present. |
+|`aria-hidden`| Accordion tabpanel attribute. An accordion should convey the visibility of each tabpanel by maintaining its aria-hidden state | Required. Added by component. |
+|`hidden`| Accordion tabpanel attribute. | Required. Added by component if `aria-hidden="true"`. |
+ 
+
+## Other examples 
+* The Accordion component is based on / inspired by this [CodePen](http://codepen.io/aann/pen/dPqBML)
+* [Open Ajax, Tab Panel: Accordian1](http://www.oaa-accessibility.org/examplep/accordian1/)
+* [www3 Accordion Example](https://www.w3.org/TR/wai-aria-practices/examples/accordion/accordion1.html)
diff --git a/node_modules/mdl-ext/src/accordion/snippets/accordion.html b/node_modules/mdl-ext/src/accordion/snippets/accordion.html
new file mode 100644
index 0000000..fae785c
--- /dev/null
+++ b/node_modules/mdl-ext/src/accordion/snippets/accordion.html
@@ -0,0 +1,1072 @@
+<p>A Collection of panels within a common outer pane.</p>
+<p><strong>Note:</strong> The accordion has been refactored and is not compatible with the accordion prior to version 0.9.13</p>
+
+
+<h4>Horizontal accordion, ripple effect, animated tabpanel, aria-multiselectable="false"</h4>
+
+<style>
+  .demo-accordion-1 {
+    height: 300px; /* In horizontal layout, the accordion must have a height */
+  }
+  .demo-accordion-1 .mdlext-accordion__tabpanel {
+    background-color: rgba(239, 154, 154, 0.4);  /* Just a trace color */
+  }
+</style>
+
+<ul class="mdlext-accordion mdlext-js-accordion mdlext-accordion--horizontal mdlext-js-ripple-effect mdlext-js-animation-effect demo-accordion-1"
+    role="tablist" aria-multiselectable="false">
+
+  <li class="mdlext-accordion__panel" role="presentation">
+    <header class="mdlext-accordion__tab" aria-expanded="true" role="tab">
+      <i class="material-icons">info</i>
+      <span class="mdlext-accordion__tab__caption">First tab. A long caption should not push the state icon</span>
+      <i class="mdlext-aria-toggle-material-icons"></i>
+    </header>
+    <section class="mdlext-accordion__tabpanel" role="tabpanel" aria-hidden="false">
+      <h5>Content #1 goes here</h5>
+      <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam tristique eget augue eget gravida.
+        Etiam eget imperdiet massa. Aliquam nisi eros, molestie a vulputate quis, tempor nec quam. Ut at libero
+        in sem pellentesque imperdiet. Praesent pretium, sapien vel mollis porttitor, felis magna vehicula metus,
+        ac dignissim odio tortor nec quam.Fusce tincidunt leo in est <a href="#">venenatis porta</a>.
+      </p>
+      <p>Maecenas eu vestibulum orci. Ut eget nisi a est sagittis euismod a vel
+        justo. Quisque at dui urna. Duis vel velit leo. Nulla nunc sem, rutrum at aliquet in, aliquet id velit. Duis
+        mattis placerat erat, a aliquam leo rhoncus vel. Sed nec diam ex. Praesent convallis purus lorem, vel porttitor
+        neque gravida quis. Etiam et malesuada dui. Nunc vitae viverra dui. Suspendisse feugiat efficitur augue, quis
+        blandit leo ullamcorper vel.
+      </p>
+      <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam tristique eget augue eget gravida.
+        Etiam eget imperdiet massa. Aliquam nisi eros, molestie a vulputate quis, tempor nec quam. Ut at libero
+        in sem pellentesque imperdiet. Praesent pretium, sapien vel mollis porttitor, felis magna vehicula metus,
+        ac dignissim odio tortor nec quam.Fusce tincidunt leo in est <a href="#">venenatis porta</a>.
+      </p>
+      <p>Maecenas eu vestibulum orci. Ut eget nisi a est sagittis euismod a vel
+        justo. Quisque at dui urna. Duis vel velit leo. Nulla nunc sem, rutrum at aliquet in, aliquet id velit. Duis
+        mattis placerat erat, a aliquam leo rhoncus vel. Sed nec diam ex. Praesent convallis purus lorem, vel porttitor
+        neque gravida quis. Etiam et malesuada dui. Nunc vitae viverra dui. Suspendisse feugiat efficitur augue, quis
+        blandit leo ullamcorper vel.
+      </p>
+    </section>
+  </li>
+  <li class="mdlext-accordion__panel" role="presentation">
+    <header class="mdlext-accordion__tab" aria-expanded="false" role="tab">
+      <span class="mdlext-accordion__tab__caption">Tab #2</span>
+      <i class="mdlext-aria-toggle-material-icons"></i>
+    </header>
+    <section class="mdlext-accordion__tabpanel" role="tabpanel" hidden aria-hidden="true">
+      <h5>Content #2 goes here</h5>
+      <p>Curabitur malesuada placerat nunc, id dapibus justo tempor in. Ut molestie
+        arcu justo, id volutpat eros vestibulum eget. Fusce tincidunt leo in est venenatis porta.
+      </p>
+    </section>
+  </li>
+  <li class="mdlext-accordion__panel" role="presentation">
+    <header class="mdlext-accordion__tab" aria-expanded="false" role="tab" disabled tabindex="0">
+      <i class="material-icons">warning</i>
+      <span class="mdlext-accordion__tab__caption">Tab #3, disabled</span>
+      <i class="mdlext-aria-toggle-material-icons"></i>
+    </header>
+    <section class="mdlext-accordion__tabpanel" role="tabpanel" hidden aria-hidden="true">
+      <h5>Content #3 goes here</h5>
+      <p>Praesent pretium, sapien vel mollis porttitor, felis magna vehicula metus,
+        ac dignissim odio tortor nec quam. Nam molestie, arcu id maximus lacinia, ante ipsum posuere mauris, ac
+        maximus massa felis quis quam. usce tincidunt leo in est venenatis porta.
+      </p>
+    </section>
+  </li>
+  <li class="mdlext-accordion__panel" role="presentation">
+    <header class="mdlext-accordion__tab" aria-expanded="false" role="tab">
+      <i class="material-icons">accessibility</i>
+      <i class="material-icons">help_outline</i>
+      <i class="material-icons">radio</i>
+      <span class="mdlext-accordion__tab__caption">Tab #4</span>
+      <i class="mdlext-aria-toggle-material-icons"></i>
+    </header>
+    <section class="mdlext-accordion__tabpanel" role="tabpanel" hidden aria-hidden="true">
+      <h5>Content #4 goes here</h5>
+      <p>Praesent pretium, sapien vel mollis porttitor, felis magna vehicula metus,
+        ac dignissim odio tortor nec quam. Nam molestie, arcu id maximus lacinia, ante ipsum posuere mauris, ac
+        maximus massa felis quis quam. usce tincidunt leo in est venenatis porta.
+      </p>
+    </section>
+  </li>
+  <li class="mdlext-accordion__panel" role="presentation">
+    <header class="mdlext-accordion__tab" aria-expanded="false" role="tab">
+      <button class="mdl-button mdl-button--icon mdl-button--colored"><i class="material-icons">favorite</i></button>
+      <button class="mdl-button mdl-button--icon mdl-button--colored"><i class="material-icons">share</i></button>
+      <span class="mdlext-accordion__tab__caption">Tab #5, with icon buttons</span>
+      <i class="mdlext-aria-toggle-material-icons"></i>
+    </header>
+    <section class="mdlext-accordion__tabpanel" role="tabpanel" hidden aria-hidden="true">
+      <h5>Content #5 goes here</h5>
+      <p>Praesent pretium, sapien vel mollis porttitor, felis magna vehicula metus,
+        ac dignissim odio tortor nec quam. Nam molestie, arcu id maximus lacinia, ante ipsum posuere mauris, ac
+        maximus massa felis quis quam. usce tincidunt leo in est venenatis porta.
+      </p>
+    </section>
+  </li>
+</ul>
+
+
+
+<h4>Horizontal accordion, aria-multiselectable="true"</h4>
+<p><strong>Hint:</strong> Use a container to draw outer borders</p>
+
+<style>
+  .demo-accordion-2-container {
+    border: 1px solid #00b0ff;
+  }
+  .demo-accordion-2 {
+    height: 313px;
+  }
+  .demo-accordion-2 .mdlext-accordion__tabpanel {
+    background-color: rgba(206, 147, 216, 0.4);
+  }
+</style>
+
+<div class="demo-accordion-2-container">
+  <ul class="mdlext-accordion mdlext-js-accordion mdlext-accordion--horizontal demo-accordion-2" role="tablist" aria-multiselectable="true">
+
+    <li class="mdlext-accordion__panel" role="presentation">
+      <header class="mdlext-accordion__tab" aria-expanded="true" role="tab">
+        <i class="material-icons">info</i>
+        <span class="mdlext-accordion__tab__caption">First section. A long caption should not push the state icon</span>
+        <i class="mdlext-aria-toggle-material-icons"></i>
+      </header>
+      <section class="mdlext-accordion__tabpanel" role="tabpanel" aria-hidden="false">
+        <h5>Content #1 goes here</h5>
+        <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam tristique eget augue eget gravida.
+          Etiam eget imperdiet massa. Aliquam nisi eros, molestie a vulputate quis, tempor nec quam. Ut at libero
+          in sem pellentesque imperdiet. Praesent pretium, sapien vel mollis porttitor, felis magna vehicula metus,
+          ac dignissim odio tortor nec quam.Fusce tincidunt leo in est <a href="#">venenatis porta</a>.
+        </p>
+        <p>Maecenas eu vestibulum orci. Ut eget nisi a est sagittis euismod a vel
+          justo. Quisque at dui urna. Duis vel velit leo. Nulla nunc sem, rutrum at aliquet in, aliquet id velit. Duis
+          mattis placerat erat, a aliquam leo rhoncus vel. Sed nec diam ex. Praesent convallis purus lorem, vel porttitor
+          neque gravida quis. Etiam et malesuada dui. Nunc vitae viverra dui. Suspendisse feugiat efficitur augue, quis
+          blandit leo ullamcorper vel.
+        </p>
+        <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam tristique eget augue eget gravida.
+          Etiam eget imperdiet massa. Aliquam nisi eros, molestie a vulputate quis, tempor nec quam. Ut at libero
+          in sem pellentesque imperdiet. Praesent pretium, sapien vel mollis porttitor, felis magna vehicula metus,
+          ac dignissim odio tortor nec quam.Fusce tincidunt leo in est <a href="#">venenatis porta</a>.
+        </p>
+        <p>Maecenas eu vestibulum orci. Ut eget nisi a est sagittis euismod a vel
+          justo. Quisque at dui urna. Duis vel velit leo. Nulla nunc sem, rutrum at aliquet in, aliquet id velit. Duis
+          mattis placerat erat, a aliquam leo rhoncus vel. Sed nec diam ex. Praesent convallis purus lorem, vel porttitor
+          neque gravida quis. Etiam et malesuada dui. Nunc vitae viverra dui. Suspendisse feugiat efficitur augue, quis
+          blandit leo ullamcorper vel.
+        </p>
+      </section>
+    </li>
+    <li class="mdlext-accordion__panel" role="presentation">
+      <header class="mdlext-accordion__tab" aria-expanded="true" role="tab">
+        <span class="mdlext-accordion__tab__caption">Tab #2</span>
+        <i class="mdlext-aria-toggle-material-icons"></i>
+      </header>
+      <section class="mdlext-accordion__tabpanel" role="tabpanel" hidden aria-hidden="true">
+        <h5>Content #2 goes here</h5>
+        <p>Curabitur malesuada placerat nunc, id dapibus justo tempor in. Ut molestie
+          arcu justo, id volutpat eros vestibulum eget. Fusce tincidunt leo in est venenatis porta.
+        </p>
+      </section>
+    </li>
+    <li class="mdlext-accordion__panel" role="presentation">
+      <header class="mdlext-accordion__tab" aria-expanded="false" role="tab" disabled tabindex="0">
+        <i class="material-icons">warning</i>
+        <span class="mdlext-accordion__tab__caption">Tab #3, disabled</span>
+        <i class="mdlext-aria-toggle-material-icons"></i>
+      </header>
+      <section class="mdlext-accordion__tabpanel" role="tabpanel" hidden aria-hidden="true">
+        <h5>Content #3 goes here</h5>
+        <p>Praesent pretium, sapien vel mollis porttitor, felis magna vehicula metus,
+          ac dignissim odio tortor nec quam. Nam molestie, arcu id maximus lacinia, ante ipsum posuere mauris, ac
+          maximus massa felis quis quam. usce tincidunt leo in est venenatis porta.
+        </p>
+      </section>
+    </li>
+    <li class="mdlext-accordion__panel" role="presentation">
+      <header class="mdlext-accordion__tab" aria-expanded="false" role="tab">
+        <i class="material-icons">accessibility</i>
+        <i class="material-icons">help_outline</i>
+        <i class="material-icons">radio</i>
+        <span class="mdlext-accordion__tab__caption">Tab #4, no toggle icon</span>
+      </header>
+      <section class="mdlext-accordion__tabpanel" role="tabpanel" hidden aria-hidden="true">
+        <h5>Content #4 goes here</h5>
+        <p>Praesent pretium, sapien vel mollis porttitor, felis magna vehicula metus,
+          ac dignissim odio tortor nec quam. Nam molestie, arcu id maximus lacinia, ante ipsum posuere mauris, ac
+          maximus massa felis quis quam. usce tincidunt leo in est venenatis porta.
+        </p>
+      </section>
+    </li>
+    <li class="mdlext-accordion__panel" role="presentation">
+      <header class="mdlext-accordion__tab" aria-expanded="false" role="tab">
+        <button class="mdl-button mdl-button--icon mdl-button--colored"><i class="material-icons">favorite</i></button>
+        <button class="mdl-button mdl-button--icon mdl-button--colored"><i class="material-icons">share</i></button>
+        <span class="mdlext-accordion__tab__caption">Tab #5, with icon buttons</span>
+        <i class="mdlext-aria-toggle-material-icons"></i>
+      </header>
+      <section class="mdlext-accordion__tabpanel" role="tabpanel" hidden aria-hidden="true">
+        <h5>Content #5 goes here</h5>
+        <p>Praesent pretium, sapien vel mollis porttitor, felis magna vehicula metus,
+          ac dignissim odio tortor nec quam. Nam molestie, arcu id maximus lacinia, ante ipsum posuere mauris, ac
+          maximus massa felis quis quam. usce tincidunt leo in est venenatis porta.
+        </p>
+      </section>
+    </li>
+  </ul>
+</div>
+
+
+
+<h4>Vertical accordion, ripple effect, animated tabpanel, aria-multiselectable="true"</h4>
+
+<style>
+  .demo-accordion-3 .mdlext-accordion__tabpanel {
+    background-color: rgba(144, 202, 249, 0.4);
+  }
+</style>
+
+<ul class="mdlext-accordion mdlext-js-accordion mdlext-accordion--vertical mdlext-js-ripple-effect mdlext-js-animation-effect demo-accordion-3"
+    role="tablist" aria-multiselectable="true">
+
+  <li class="mdlext-accordion__panel" role="presentation">
+    <header class="mdlext-accordion__tab" aria-expanded="true" role="tab">
+      <i class="material-icons">info</i>
+      <span class="mdlext-accordion__tab__caption">First section. A long caption should not push the state icon</span>
+      <i class="mdlext-aria-toggle-material-icons"></i>
+    </header>
+    <section class="mdlext-accordion__tabpanel" role="tabpanel" aria-hidden="false">
+      <h5>Content #1 goes here</h5>
+      <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam tristique eget augue eget gravida.
+        Etiam eget imperdiet massa. Aliquam nisi eros, molestie a vulputate quis, tempor nec quam. Ut at libero
+        in sem pellentesque imperdiet. Praesent pretium, sapien vel mollis porttitor, felis magna vehicula metus,
+        ac dignissim odio tortor nec quam.Fusce tincidunt leo in est <a href="#">venenatis porta</a>.
+      </p>
+      <p>Maecenas eu vestibulum orci. Ut eget nisi a est sagittis euismod a vel
+        justo. Quisque at dui urna. Duis vel velit leo. Nulla nunc sem, rutrum at aliquet in, aliquet id velit. Duis
+        mattis placerat erat, a aliquam leo rhoncus vel. Sed nec diam ex. Praesent convallis purus lorem, vel porttitor
+        neque gravida quis. Etiam et malesuada dui. Nunc vitae viverra dui. Suspendisse feugiat efficitur augue, quis
+        blandit leo ullamcorper vel.
+      </p>
+    </section>
+  </li>
+  <li class="mdlext-accordion__panel" role="presentation">
+    <header class="mdlext-accordion__tab" aria-expanded="false" role="tab">
+      <span class="mdlext-accordion__tab__caption">Tab #2</span>
+      <i class="mdlext-aria-toggle-material-icons"></i>
+    </header>
+    <section class="mdlext-accordion__tabpanel" role="tabpanel" hidden aria-hidden="true">
+      <h5>Content #2 goes here</h5>
+      <p>Curabitur malesuada placerat nunc, id dapibus justo tempor in. Ut molestie
+        arcu justo, id volutpat eros vestibulum eget. Fusce tincidunt leo in est venenatis porta.
+      </p>
+    </section>
+  </li>
+  <li class="mdlext-accordion__panel" role="presentation">
+    <header class="mdlext-accordion__tab" aria-expanded="false" role="tab" disabled tabindex="0">
+      <i class="material-icons">warning</i>
+      <span class="mdlext-accordion__tab__caption">Tab #3, disabled</span>
+      <i class="mdlext-aria-toggle-material-icons"></i>
+    </header>
+    <section class="mdlext-accordion__tabpanel" role="tabpanel" hidden aria-hidden="true">
+      <h5>Content #3 goes here</h5>
+      <p>Praesent pretium, sapien vel mollis porttitor, felis magna vehicula metus,
+        ac dignissim odio tortor nec quam. Nam molestie, arcu id maximus lacinia, ante ipsum posuere mauris, ac
+        maximus massa felis quis quam. usce tincidunt leo in est venenatis porta.
+      </p>
+    </section>
+  </li>
+  <li class="mdlext-accordion__panel" role="presentation">
+    <header class="mdlext-accordion__tab" aria-expanded="false" role="tab">
+      <i class="material-icons">accessibility</i>
+      <i class="material-icons">help_outline</i>
+      <i class="material-icons">radio</i>
+      <span class="mdlext-accordion__tab__caption">Tab #4, no toggle icon</span>
+    </header>
+    <section class="mdlext-accordion__tabpanel" role="tabpanel" hidden aria-hidden="true">
+      <h5>Content #4 goes here</h5>
+      <p>Praesent pretium, sapien vel mollis porttitor, felis magna vehicula metus,
+        ac dignissim odio tortor nec quam. Nam molestie, arcu id maximus lacinia, ante ipsum posuere mauris, ac
+        maximus massa felis quis quam. usce tincidunt leo in est venenatis porta.
+      </p>
+    </section>
+  </li>
+  <li class="mdlext-accordion__panel" role="presentation">
+    <header class="mdlext-accordion__tab" aria-expanded="true" role="tab">
+      <button class="mdl-button mdl-button--icon mdl-button--colored"><i class="material-icons">favorite</i></button>
+      <button class="mdl-button mdl-button--icon mdl-button--colored"><i class="material-icons">share</i></button>
+      <span class="mdlext-accordion__tab__caption">Tab #5, with icon buttons</span>
+      <i class="mdlext-aria-toggle-material-icons"></i>
+    </header>
+    <section class="mdlext-accordion__tabpanel" role="tabpanel">
+      <h5>Content #5 goes here</h5>
+      <p>Praesent pretium, sapien vel mollis porttitor, felis magna vehicula metus,
+        ac dignissim odio tortor nec quam. Nam molestie, arcu id maximus lacinia, ante ipsum posuere mauris, ac
+        maximus massa felis quis quam. usce tincidunt leo in est venenatis porta.
+      </p>
+    </section>
+  </li>
+</ul>
+
+
+<h4>Vertical accordion, aria-multiselectable="false"</h4>
+<p><strong>Hint:</strong> Use a container to draw outer borders</p>
+
+<style>
+  .demo-accordion-4 {
+    height: 500px;
+    border: 1px solid #00b0ff;
+  }
+  .demo-accordion-4 .mdlext-accordion__tabpanel {
+    background-color: rgba(165, 214, 167, 0.4);
+  }
+</style>
+
+<ul class="mdlext-accordion mdlext-js-accordion mdlext-accordion--vertical demo-accordion-4" role="tablist" aria-multiselectable="false">
+
+  <li class="mdlext-accordion__panel" role="presentation">
+    <header class="mdlext-accordion__tab" aria-expanded="false" role="tab">
+      <i class="material-icons">info</i>
+      <span class="mdlext-accordion__tab__caption">First section. A long caption should not push the state icon</span>
+      <i class="mdlext-aria-toggle-material-icons"></i>
+    </header>
+    <section class="mdlext-accordion__tabpanel" role="tabpanel">
+      <h5>Content #1 goes here</h5>
+      <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam tristique eget augue eget gravida.
+        Etiam eget imperdiet massa. Aliquam nisi eros, molestie a vulputate quis, tempor nec quam. Ut at libero
+        in sem pellentesque imperdiet. Praesent pretium, sapien vel mollis porttitor, felis magna vehicula metus,
+        ac dignissim odio tortor nec quam.Fusce tincidunt leo in est <a href="#">venenatis porta</a>.
+      </p>
+      <p>Maecenas eu vestibulum orci. Ut eget nisi a est sagittis euismod a vel
+        justo. Quisque at dui urna. Duis vel velit leo. Nulla nunc sem, rutrum at aliquet in, aliquet id velit. Duis
+        mattis placerat erat, a aliquam leo rhoncus vel. Sed nec diam ex. Praesent convallis purus lorem, vel porttitor
+        neque gravida quis. Etiam et malesuada dui. Nunc vitae viverra dui. Suspendisse feugiat efficitur augue, quis
+        blandit leo ullamcorper vel.
+      </p>
+      <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam tristique eget augue eget gravida.
+        Etiam eget imperdiet massa. Aliquam nisi eros, molestie a vulputate quis, tempor nec quam. Ut at libero
+        in sem pellentesque imperdiet. Praesent pretium, sapien vel mollis porttitor, felis magna vehicula metus,
+        ac dignissim odio tortor nec quam.Fusce tincidunt leo in est <a href="#">venenatis porta</a>.
+      </p>
+    </section>
+  </li>
+  <li class="mdlext-accordion__panel" role="presentation">
+    <header class="mdlext-accordion__tab" aria-expanded="true" role="tab">
+      <span class="mdlext-accordion__tab__caption">Tab #2</span>
+      <i class="mdlext-aria-toggle-material-icons"></i>
+    </header>
+    <section class="mdlext-accordion__tabpanel" role="tabpanel">
+      <h5>Content #2 goes here</h5>
+      <p>Curabitur malesuada placerat nunc, id dapibus justo tempor in. Ut molestie
+        arcu justo, id volutpat eros vestibulum eget. Fusce tincidunt leo in est venenatis porta.
+      </p>
+    </section>
+  </li>
+  <li class="mdlext-accordion__panel" role="presentation">
+    <header class="mdlext-accordion__tab" aria-expanded="false" role="tab" disabled>
+      <i class="material-icons">warning</i>
+      <span class="mdlext-accordion__tab__caption">Tab #3, disabled</span>
+      <i class="mdlext-aria-toggle-material-icons"></i>
+    </header>
+    <section class="mdlext-accordion__tabpanel" role="tabpanel" hidden aria-hidden="true">
+      <h5>Content #3 goes here</h5>
+      <p>Praesent pretium, sapien vel mollis porttitor, felis magna vehicula metus,
+        ac dignissim odio tortor nec quam. Nam molestie, arcu id maximus lacinia, ante ipsum posuere mauris, ac
+        maximus massa felis quis quam. usce tincidunt leo in est venenatis porta.
+      </p>
+    </section>
+  </li>
+  <li class="mdlext-accordion__panel" role="presentation">
+    <header class="mdlext-accordion__tab" aria-expanded="false" role="tab">
+      <i class="material-icons">accessibility</i>
+      <i class="material-icons">help_outline</i>
+      <i class="material-icons">radio</i>
+      <span class="mdlext-accordion__tab__caption">Tab #4</span>
+      <i class="mdlext-aria-toggle-material-icons"></i>
+    </header>
+    <section class="mdlext-accordion__tabpanel" role="tabpanel">
+      <h5>Content #4 goes here</h5>
+      <p>Praesent pretium, sapien vel mollis porttitor, felis magna vehicula metus,
+        ac dignissim odio tortor nec quam. Nam molestie, arcu id maximus lacinia, ante ipsum posuere mauris, ac
+        maximus massa felis quis quam. usce tincidunt leo in est venenatis porta.
+      </p>
+    </section>
+  </li>
+  <li class="mdlext-accordion__panel" role="presentation">
+    <header class="mdlext-accordion__tab" aria-expanded="false" role="tab">
+      <button class="mdl-button mdl-button--icon mdl-button--colored"><i class="material-icons">favorite</i></button>
+      <button class="mdl-button mdl-button--icon mdl-button--colored"><i class="material-icons">share</i></button>
+      <span class="mdlext-accordion__tab__caption">Tab #5, with icon buttons</span>
+      <i class="mdlext-aria-toggle-material-icons"></i>
+    </header>
+    <section class="mdlext-accordion__tabpanel" role="tabpanel">
+      <h5>Content #5 goes here</h5>
+      <p>Praesent pretium, sapien vel mollis porttitor, felis magna vehicula metus,
+        ac dignissim odio tortor nec quam. Nam molestie, arcu id maximus lacinia, ante ipsum posuere mauris, ac
+        maximus massa felis quis quam. usce tincidunt leo in est venenatis porta.
+      </p>
+    </section>
+  </li>
+</ul>
+
+
+<h4>Disabled accordion</h4>
+<ul class="mdlext-accordion mdlext-js-accordion mdlext-accordion--horizontal demo-accordion-1"
+    role="tablist" aria-multiselectable="false" disabled>
+
+  <li class="mdlext-accordion__panel" role="presentation">
+    <header class="mdlext-accordion__tab" aria-expanded="true" role="tab">
+      <i class="material-icons">info</i>
+      <span class="mdlext-accordion__tab__caption">First section. A long caption should not push the state icon</span>
+      <i class="mdlext-aria-toggle-material-icons"></i>
+    </header>
+    <section class="mdlext-accordion__tabpanel" role="tabpanel" aria-hidden="false">
+      <h5>Content goes here</h5>
+      <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam tristique eget augue eget gravida.
+        Etiam eget imperdiet massa. Aliquam nisi eros, molestie a vulputate quis, tempor nec quam. Ut at libero
+        in sem pellentesque imperdiet. Praesent pretium, sapien vel mollis porttitor, felis magna vehicula metus,
+        ac dignissim odio tortor nec quam.Fusce tincidunt leo in est <a href="#">venenatis porta</a>.
+      </p>
+      <p>Maecenas eu vestibulum orci. Ut eget nisi a est sagittis euismod a vel
+        justo. Quisque at dui urna. Duis vel velit leo. Nulla nunc sem, rutrum at aliquet in, aliquet id velit. Duis
+        mattis placerat erat, a aliquam leo rhoncus vel. Sed nec diam ex. Praesent convallis purus lorem, vel porttitor
+        neque gravida quis. Etiam et malesuada dui. Nunc vitae viverra dui. Suspendisse feugiat efficitur augue, quis
+        blandit leo ullamcorper vel.
+      </p>
+      <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam tristique eget augue eget gravida.
+        Etiam eget imperdiet massa. Aliquam nisi eros, molestie a vulputate quis, tempor nec quam. Ut at libero
+        in sem pellentesque imperdiet. Praesent pretium, sapien vel mollis porttitor, felis magna vehicula metus,
+        ac dignissim odio tortor nec quam.Fusce tincidunt leo in est <a href="#">venenatis porta</a>.
+      </p>
+      <p>Maecenas eu vestibulum orci. Ut eget nisi a est sagittis euismod a vel
+        justo. Quisque at dui urna. Duis vel velit leo. Nulla nunc sem, rutrum at aliquet in, aliquet id velit. Duis
+        mattis placerat erat, a aliquam leo rhoncus vel. Sed nec diam ex. Praesent convallis purus lorem, vel porttitor
+        neque gravida quis. Etiam et malesuada dui. Nunc vitae viverra dui. Suspendisse feugiat efficitur augue, quis
+        blandit leo ullamcorper vel.
+      </p>
+    </section>
+  </li>
+  <li class="mdlext-accordion__panel" role="presentation">
+    <header class="mdlext-accordion__tab" aria-expanded="false" role="tab">
+      <span class="mdlext-accordion__tab__caption">Tab #2</span>
+      <i class="mdlext-aria-toggle-material-icons"></i>
+    </header>
+    <section class="mdlext-accordion__tabpanel" role="tabpanel" hidden aria-hidden="true">
+    </section>
+  </li>
+  <li class="mdlext-accordion__panel" role="presentation">
+    <header class="mdlext-accordion__tab" aria-expanded="false" role="tab" disabled tabindex="0">
+      <i class="material-icons">warning</i>
+      <span class="mdlext-accordion__tab__caption">Tab #3, disabled</span>
+      <i class="mdlext-aria-toggle-material-icons"></i>
+    </header>
+    <section class="mdlext-accordion__tabpanel" role="tabpanel" hidden aria-hidden="true">
+    </section>
+  </li>
+  <li class="mdlext-accordion__panel" role="presentation">
+    <header class="mdlext-accordion__tab" aria-expanded="false" role="tab">
+      <i class="material-icons">accessibility</i>
+      <i class="material-icons">help_outline</i>
+      <i class="material-icons">radio</i>
+      <span class="mdlext-accordion__tab__caption">Tab #4</span>
+      <i class="mdlext-aria-toggle-material-icons"></i>
+    </header>
+    <section class="mdlext-accordion__tabpanel" role="tabpanel" hidden aria-hidden="true">
+    </section>
+  </li>
+  <li class="mdlext-accordion__panel" role="presentation">
+    <header class="mdlext-accordion__tab" aria-expanded="false" role="tab">
+      <button class="mdl-button mdl-button--icon mdl-button--colored"><i class="material-icons">favorite</i></button>
+      <button class="mdl-button mdl-button--icon mdl-button--colored"><i class="material-icons">share</i></button>
+      <span class="mdlext-accordion__tab__caption">Tab #5, with icon buttons</span>
+      <i class="mdlext-aria-toggle-material-icons"></i>
+    </header>
+    <section class="mdlext-accordion__tabpanel" role="tabpanel" hidden aria-hidden="true">
+    </section>
+  </li>
+</ul>
+
+
+
+
+<h4>Accordion API</h4>
+
+<style>
+  .cmd-button {
+    min-width: 140px;
+  }
+  .demo-accordion-6 .mdlext-accordion__tabpanel {
+    background: rgba(255, 224, 130, 0.4);
+  }
+</style>
+
+<h5>Public methods</h5>
+
+<section style="margin-bottom: 16px">
+  <button id="btn-api-expand-all" class="cmd-button mdl-button mdl-js-button mdl-button--raised">
+    Expand all
+  </button>
+  <button id="btn-api-collapse-all" class="cmd-button mdl-button mdl-js-button mdl-button--raised">
+    Collapse all
+  </button>
+  <button id="btn-api-open-tab2" class="cmd-button mdl-button mdl-js-button mdl-button--raised">
+    Open tab #2
+  </button>
+  <button id="btn-api-close-tab2" class="cmd-button mdl-button mdl-js-button mdl-button--raised">
+    Close tab #2
+  </button>
+  <button id="btn-api-toggle-tab2" class="cmd-button mdl-button mdl-js-button mdl-button--raised">
+    Toggle tab #2
+  </button>
+  <button id="btn-api-new-tab" class="cmd-button mdl-button mdl-js-button mdl-button--raised">
+    Add a new tab
+  </button>
+</section>
+
+<h5>Custom events</h5>
+
+<section style="margin-bottom: 16px">
+  <button id="btn-event-expand-all" class="cmd-button mdl-button mdl-js-button mdl-button--raised">
+    Expand all
+  </button>
+  <button id="btn-event-collapse-all" class="cmd-button mdl-button mdl-js-button mdl-button--raised">
+    Collapse all
+  </button>
+  <button id="btn-event-open-tab2" class="cmd-button mdl-button mdl-js-button mdl-button--raised">
+    Open tab #2
+  </button>
+  <button id="btn-event-close-tab2" class="cmd-button mdl-button mdl-js-button mdl-button--raised">
+    Close tab #2
+  </button>
+  <button id="btn-event-toggle-tab2" class="cmd-button mdl-button mdl-js-button mdl-button--raised">
+    Toggle tab #2
+  </button>
+  <button id="btn-event-new-tab" class="cmd-button mdl-button mdl-js-button mdl-button--raised">
+    Add a new tab
+  </button>
+</section>
+
+
+<ul id="demo-accordion-6" class="mdlext-accordion mdlext-js-accordion mdlext-accordion--vertical demo-accordion-6"
+    role="tablist" aria-multiselectable="true">
+
+  <li class="mdlext-accordion__panel" role="presentation">
+    <header class="mdlext-accordion__tab" aria-expanded="true" role="tab">
+      <i class="material-icons">info</i>
+      <span class="mdlext-accordion__tab__caption">Tab #1</span>
+      <i class="mdlext-aria-toggle-material-icons"></i>
+    </header>
+    <section class="mdlext-accordion__tabpanel" role="tabpanel" aria-hidden="false">
+      <h5>Content #1 goes here</h5>
+      <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam tristique eget augue eget gravida.
+        Etiam eget imperdiet massa. Aliquam nisi eros, molestie a vulputate quis, tempor nec quam. Ut at libero
+        in sem pellentesque imperdiet. Praesent pretium, sapien vel mollis porttitor, felis magna vehicula metus,
+        ac dignissim odio tortor nec quam.Fusce tincidunt leo in est <a href="#">venenatis porta</a>.
+      </p>
+      <p>Maecenas eu vestibulum orci. Ut eget nisi a est sagittis euismod a vel
+        justo. Quisque at dui urna. Duis vel velit leo. Nulla nunc sem, rutrum at aliquet in, aliquet id velit. Duis
+        mattis placerat erat, a aliquam leo rhoncus vel. Sed nec diam ex. Praesent convallis purus lorem, vel porttitor
+        neque gravida quis. Etiam et malesuada dui. Nunc vitae viverra dui. Suspendisse feugiat efficitur augue, quis
+        blandit leo ullamcorper vel.
+      </p>
+    </section>
+  </li>
+  <li class="mdlext-accordion__panel" role="presentation">
+    <header class="mdlext-accordion__tab" aria-expanded="false" role="tab">
+      <span class="mdlext-accordion__tab__caption">Tab #2</span>
+      <i class="mdlext-aria-toggle-material-icons"></i>
+    </header>
+    <section class="mdlext-accordion__tabpanel" role="tabpanel" hidden aria-hidden="true">
+      <h5>Content #2 goes here</h5>
+      <p>Curabitur malesuada placerat nunc, id dapibus justo tempor in. Ut molestie
+        arcu justo, id volutpat eros vestibulum eget. Fusce tincidunt leo in est venenatis porta.
+      </p>
+    </section>
+  </li>
+  <li class="mdlext-accordion__panel" role="presentation">
+    <header class="mdlext-accordion__tab" aria-expanded="false" role="tab" disabled tabindex="0">
+      <i class="material-icons">warning</i>
+      <span class="mdlext-accordion__tab__caption">Tab #3, disabled</span>
+      <i class="mdlext-aria-toggle-material-icons"></i>
+    </header>
+    <section class="mdlext-accordion__tabpanel" role="tabpanel" hidden aria-hidden="true">
+      <h5>Content #3 goes here</h5>
+      <p>Praesent pretium, sapien vel mollis porttitor, felis magna vehicula metus,
+        ac dignissim odio tortor nec quam. Nam molestie, arcu id maximus lacinia, ante ipsum posuere mauris, ac
+        maximus massa felis quis quam. usce tincidunt leo in est venenatis porta.
+      </p>
+    </section>
+  </li>
+  <li class="mdlext-accordion__panel" role="presentation">
+    <header class="mdlext-accordion__tab" aria-expanded="false" role="tab">
+      <i class="material-icons">accessibility</i>
+      <i class="material-icons">help_outline</i>
+      <i class="material-icons">radio</i>
+      <span class="mdlext-accordion__tab__caption">Tab #4</span>
+      <i class="mdlext-aria-toggle-material-icons"></i>
+    </header>
+    <section class="mdlext-accordion__tabpanel" role="tabpanel" hidden aria-hidden="true">
+      <h5>Content #4 goes here</h5>
+      <p>Praesent pretium, sapien vel mollis porttitor, felis magna vehicula metus,
+        ac dignissim odio tortor nec quam. Nam molestie, arcu id maximus lacinia, ante ipsum posuere mauris, ac
+        maximus massa felis quis quam. usce tincidunt leo in est venenatis porta.
+      </p>
+    </section>
+  </li>
+  <li class="mdlext-accordion__panel" role="presentation">
+    <header class="mdlext-accordion__tab" aria-expanded="false" role="tab">
+      <button class="mdl-button mdl-button--icon mdl-button--colored"><i class="material-icons">favorite</i></button>
+      <button class="mdl-button mdl-button--icon mdl-button--colored"><i class="material-icons">share</i></button>
+      <span class="mdlext-accordion__tab__caption">Tab #5, with icon buttons</span>
+      <i class="mdlext-aria-toggle-material-icons"></i>
+    </header>
+    <section class="mdlext-accordion__tabpanel" role="tabpanel">
+      <h5>Content #5 goes here</h5>
+      <p>Praesent pretium, sapien vel mollis porttitor, felis magna vehicula metus,
+        ac dignissim odio tortor nec quam. Nam molestie, arcu id maximus lacinia, ante ipsum posuere mauris, ac
+        maximus massa felis quis quam. usce tincidunt leo in est venenatis porta.
+      </p>
+    </section>
+  </li>
+</ul>
+
+
+
+<h4>Styling the accordion</h4>
+
+<style>
+  .demo-accordion-7 {
+    height: 300px;
+  }
+  .demo-accordion-7 .mdlext-accordion__panel,
+  .demo-accordion-7 .mdlext-accordion__tab {
+    min-width: 40px;
+    min-height: 40px;
+    width: 40px;
+  }
+  .colored-panel:nth-child(1) {
+    background: rgba(239, 154, 154, 0.4);
+  }
+  .colored-panel:nth-child(2) {
+    background: rgba(206, 147, 216, 0.4);
+  }
+  .colored-panel:nth-child(3) {
+    background: rgba(144, 202, 249, 0.4);
+  }
+  .colored-panel:nth-child(4) {
+    background: rgba(165, 214, 167, 0.4);
+  }
+  .colored-panel:nth-child(5) {
+    background: rgba(255, 224, 130, 0.4);
+  }
+  .mdlext-aria-toggle-plus-minus {
+    font-size: 20px;
+  }
+  .img-box {
+    background-size: cover;
+    background-position: center;
+    background-repeat: no-repeat;
+  }
+  .img-box--6 {
+    background-image: url(./images/_D806374.jpg);
+    background-image: linear-gradient(to bottom, rgba(255,255,255,0.2) 0%,rgba(255,255,255,0.2) 100%), url(./images/_D806374.jpg);
+  }
+  .img-box--7 {
+    background-image: url('./images/_D802478.jpg');
+    background-image: linear-gradient(to bottom, rgba(255,255,255,0.1) 0%,rgba(255,255,255,0.1) 100%), url(./images/_D802478.jpg);
+  }
+  .img-box--8 {
+    background-image: url('./images/_D803221.jpg');
+    background-image: linear-gradient(to bottom, rgba(255,255,255,0.5) 0%,rgba(255,255,255,0.5) 100%), url(./images/_D803221.jpg);
+  }
+  .img-box--9 {
+    background-image: url('./images/_D802143-2.jpg');
+    background-image: linear-gradient(to bottom, rgba(255,255,255,0.2) 0%,rgba(255,255,255,0.2) 100%), url(./images/_D802143-2.jpg);
+  }
+  .img-box--10 {
+    background-image: url('./images/_D809758-2.jpg');
+    background-image: linear-gradient(to bottom, rgba(255,255,255,0.1) 0%,rgba(255,255,255,0.1) 100%), url(./images/_D809758-2.jpg);
+  }
+</style>
+
+<ul id="demo-accordion-7" class="mdlext-accordion mdlext-js-accordion mdlext-accordion--horizontal mdlext-js-ripple-effect mdlext-js-animation-effect demo-accordion-7">
+  <li class="mdlext-accordion__panel colored-panel">
+    <header class="mdlext-accordion__tab" aria-expanded="true">
+      <i class="material-icons md-16">dns</i>
+      <span class="mdlext-accordion__tab__caption mdl-typography--subhead-color-contrast">Accordion</span>
+      <i class="mdlext-aria-toggle-plus-minus"></i>
+    </header>
+    <section class="mdlext-accordion__tabpanel img-box img-box--6">
+      <h5>Introduction</h5>
+      <p>An accordion component is a collection of expandable panels associated with a common outer container. Panels consist
+        of a header and an associated content region or panel. The primary use of an Accordion is to present multiple sections
+        of content on a single page without scrolling, where all of the sections are peers in the application or object hierarchy.
+        The general look is similar to a tree where each root tree node is an expandable accordion header. The user navigates
+        and makes the contents of each panel visible (or not) by interacting with the Accordion Header.</p>
+    </section>
+  </li>
+  <li class="mdlext-accordion__panel colored-panel">
+    <header class="mdlext-accordion__tab">
+      <i class="material-icons md-16">all_inclusive</i>
+      <span class="mdlext-accordion__tab__caption mdl-typography--subhead-color-contrast">Include Component</span>
+      <i class="mdlext-aria-toggle-plus-minus"></i>
+    </header>
+    <section class="mdlext-accordion__tabpanel img-box img-box--7">
+      <p style = "margin-top:128px;">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam tristique eget augue eget gravida.
+        Etiam eget imperdiet massa. Aliquam nisi eros, molestie a vulputate quis, tempor nec quam. Ut at libero
+        in sem pellentesque imperdiet. Praesent pretium, sapien vel mollis porttitor, felis magna vehicula metus,
+        ac dignissim odio tortor nec quam. Nam molestie, arcu id maximus lacinia, ante ipsum posuere mauris, ac
+        maximus massa felis quis quam. Curabitur malesuada placerat nunc, id dapibus justo tempor in. Ut molestie
+        arcu justo, id volutpat eros vestibulum eget. Fusce tincidunt leo in est venenatis porta.</p>
+      <p>Maecenas eu vestibulum orci. Ut eget nisi a est sagittis euismod a vel
+        justo. Quisque at dui urna. Duis vel velit leo. Nulla nunc sem, rutrum at aliquet in, aliquet id velit. Duis
+        mattis placerat erat, a aliquam leo rhoncus vel. Sed nec diam ex. Praesent convallis purus lorem, vel porttitor
+        neque gravida quis. Etiam et malesuada dui. Nunc vitae viverra dui. Suspendisse feugiat efficitur augue, quis
+        blandit leo ullamcorper vel.</p>
+      <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam tristique eget augue eget gravida.
+        Etiam eget imperdiet massa. Aliquam nisi eros, molestie a vulputate quis, tempor nec quam. Ut at libero
+        in sem pellentesque imperdiet. Praesent pretium, sapien vel mollis porttitor, felis magna vehicula metus,
+        ac dignissim odio tortor nec quam. Nam molestie, arcu id maximus lacinia, ante ipsum posuere mauris, ac
+        maximus massa felis quis quam. Curabitur malesuada placerat nunc, id dapibus justo tempor in. Ut molestie
+        arcu justo, id volutpat eros vestibulum eget. Fusce tincidunt leo in est venenatis porta.</p>
+    </section>
+  </li>
+  <li class="mdlext-accordion__panel colored-panel">
+    <header class="mdlext-accordion__tab">
+      <i class="material-icons md-16">build</i>
+      <span class="mdlext-accordion__tab__caption mdl-typography--subhead-color-contrast">Configuration Options</span>
+      <i class="mdlext-aria-toggle-plus-minus"></i>
+    </header>
+    <section class="mdlext-accordion__tabpanel img-box img-box--8">
+      <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam tristique eget augue eget gravida.
+        Etiam eget imperdiet massa. Aliquam nisi eros, molestie a vulputate quis, tempor nec quam. Ut at libero
+        in sem pellentesque imperdiet. Praesent pretium, sapien vel mollis porttitor, felis magna vehicula metus,
+        ac dignissim odio tortor nec quam. Nam molestie, arcu id maximus lacinia, ante ipsum posuere mauris, ac
+        maximus massa felis quis quam. Curabitur malesuada placerat nunc, id dapibus justo tempor in. Ut molestie
+        arcu justo, id volutpat eros vestibulum eget. Fusce tincidunt leo in est venenatis porta.</p>
+    </section>
+  </li>
+  <li class="mdlext-accordion__panel colored-panel">
+    <header class="mdlext-accordion__tab">
+      <i class="material-icons md-16">public</i>
+      <span class="mdlext-accordion__tab__caption mdl-typography--subhead-color-contrast">Fourth section</span>
+      <i class="mdlext-aria-toggle-plus-minus"></i>
+    </header>
+    <section class="mdlext-accordion__tabpanel img-box img-box--9">
+      <p>Maecenas eu vestibulum orci. Ut eget nisi a est sagittis euismod a vel
+        justo. Quisque at dui urna. Duis vel velit leo. Nulla nunc sem, rutrum at aliquet in, aliquet id velit. Duis
+        mattis placerat erat, a aliquam leo rhoncus vel. Sed nec diam ex. Praesent convallis purus lorem, vel porttitor
+        neque gravida quis. Etiam et malesuada dui. Nunc vitae viverra dui. Suspendisse feugiat efficitur augue, quis
+        blandit leo ullamcorper vel.</p>
+    </section>
+  </li>
+  <li class="mdlext-accordion__panel colored-panel">
+    <header class="mdlext-accordion__tab">
+      <i class="material-icons md-16">public</i>
+      <span class="mdlext-accordion__tab__caption mdl-typography--subhead-color-contrast">Fifth</span>
+      <i class="mdlext-aria-toggle-plus-minus"></i>
+    </header>
+    <section class="mdlext-accordion__tabpanel img-box img-box--10">
+      <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam tristique eget augue eget gravida.
+        Etiam eget imperdiet massa. Aliquam nisi eros, molestie a vulputate quis, tempor nec quam. Ut at libero
+        in sem pellentesque imperdiet. Praesent pretium, sapien vel mollis porttitor, felis magna vehicula metus,
+        ac dignissim odio tortor nec quam. Nam molestie, arcu id maximus lacinia, ante ipsum posuere mauris, ac
+        maximus massa felis quis quam. Curabitur malesuada placerat nunc, id dapibus justo tempor in. Ut molestie
+        arcu justo, id volutpat eros vestibulum eget. Fusce tincidunt leo in est venenatis porta.</p>
+    </section>
+  </li>
+</ul>
+
+
+
+<h4>Color themes</h4>
+
+<div class="mdl-grid">
+  <div class="mdl-cell mdl-cell--6-col mdl-cell--4-col-tablet mdl-cell--2-col-phone mdlext-dark-color-theme">
+
+    <ul class="mdlext-accordion mdlext-js-accordion mdlext-accordion--vertical mdlext-js-ripple-effect mdlext-js-animation-effect"
+        role="tablist" aria-multiselectable="true">
+
+      <li class="mdlext-accordion__panel" role="presentation">
+        <header class="mdlext-accordion__tab" aria-expanded="true" role="tab">
+          <i class="material-icons">info</i>
+          <span class="mdlext-accordion__tab__caption">First section. A long caption should not push the state icon</span>
+          <i class="mdlext-aria-toggle-material-icons"></i>
+        </header>
+        <section class="mdlext-accordion__tabpanel" role="tabpanel" aria-hidden="false">
+          <h5>Content #1 goes here</h5>
+          <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam tristique eget augue eget gravida.
+            Etiam eget imperdiet massa. Aliquam nisi eros, molestie a vulputate quis, tempor nec quam. Ut at libero
+            in sem pellentesque imperdiet. Praesent pretium, sapien vel mollis porttitor, felis magna vehicula metus,
+            ac dignissim odio tortor nec quam.Fusce tincidunt leo in est <a href="#">venenatis porta</a>.
+          </p>
+          <p>Maecenas eu vestibulum orci. Ut eget nisi a est sagittis euismod a vel
+            justo. Quisque at dui urna. Duis vel velit leo. Nulla nunc sem, rutrum at aliquet in, aliquet id velit. Duis
+            mattis placerat erat, a aliquam leo rhoncus vel. Sed nec diam ex. Praesent convallis purus lorem, vel porttitor
+            neque gravida quis. Etiam et malesuada dui. Nunc vitae viverra dui. Suspendisse feugiat efficitur augue, quis
+            blandit leo ullamcorper vel.
+          </p>
+        </section>
+      </li>
+      <li class="mdlext-accordion__panel" role="presentation">
+        <header class="mdlext-accordion__tab" aria-expanded="false" role="tab">
+          <span class="mdlext-accordion__tab__caption">Tab #2</span>
+          <i class="mdlext-aria-toggle-material-icons"></i>
+        </header>
+        <section class="mdlext-accordion__tabpanel" role="tabpanel" hidden aria-hidden="true">
+          <h5>Content #2 goes here</h5>
+          <p>Curabitur malesuada placerat nunc, id dapibus justo tempor in. Ut molestie
+            arcu justo, id volutpat eros vestibulum eget. Fusce tincidunt leo in est venenatis porta.
+          </p>
+        </section>
+      </li>
+      <li class="mdlext-accordion__panel" role="presentation">
+        <header class="mdlext-accordion__tab" aria-expanded="false" role="tab" disabled tabindex="0">
+          <i class="material-icons">warning</i>
+          <span class="mdlext-accordion__tab__caption">Tab #3, disabled</span>
+          <i class="mdlext-aria-toggle-material-icons"></i>
+        </header>
+        <section class="mdlext-accordion__tabpanel" role="tabpanel" hidden aria-hidden="true">
+          <h5>Content #3 goes here</h5>
+          <p>Praesent pretium, sapien vel mollis porttitor, felis magna vehicula metus,
+            ac dignissim odio tortor nec quam. Nam molestie, arcu id maximus lacinia, ante ipsum posuere mauris, ac
+            maximus massa felis quis quam. usce tincidunt leo in est venenatis porta.
+          </p>
+        </section>
+      </li>
+      <li class="mdlext-accordion__panel" role="presentation">
+        <header class="mdlext-accordion__tab" aria-expanded="false" role="tab">
+          <i class="material-icons">accessibility</i>
+          <i class="material-icons">help_outline</i>
+          <i class="material-icons">radio</i>
+          <span class="mdlext-accordion__tab__caption">Tab #4, no toggle icon</span>
+        </header>
+        <section class="mdlext-accordion__tabpanel" role="tabpanel" hidden aria-hidden="true">
+          <h5>Content #4 goes here</h5>
+          <p>Praesent pretium, sapien vel mollis porttitor, felis magna vehicula metus,
+            ac dignissim odio tortor nec quam. Nam molestie, arcu id maximus lacinia, ante ipsum posuere mauris, ac
+            maximus massa felis quis quam. usce tincidunt leo in est venenatis porta.
+          </p>
+        </section>
+      </li>
+      <li class="mdlext-accordion__panel" role="presentation">
+        <header class="mdlext-accordion__tab" role="tab">
+          <button class="mdl-button mdl-button--icon mdl-button--colored"><i class="material-icons">favorite</i></button>
+          <button class="mdl-button mdl-button--icon mdl-button--colored"><i class="material-icons">share</i></button>
+          <span class="mdlext-accordion__tab__caption">Tab #5, with icon buttons</span>
+          <i class="mdlext-aria-toggle-material-icons"></i>
+        </header>
+        <section class="mdlext-accordion__tabpanel" role="tabpanel">
+          <h5>Content #5 goes here</h5>
+          <p>Praesent pretium, sapien vel mollis porttitor, felis magna vehicula metus,
+            ac dignissim odio tortor nec quam. Nam molestie, arcu id maximus lacinia, ante ipsum posuere mauris, ac
+            maximus massa felis quis quam. usce tincidunt leo in est venenatis porta.
+          </p>
+        </section>
+      </li>
+    </ul>
+  </div>  <!-- mdl-cell -->
+
+  <div class="mdl-cell mdl-cell--6-col mdl-cell--4-col-tablet mdl-cell--2-col-phone">
+    <ul class="mdlext-accordion mdlext-js-accordion mdlext-accordion--vertical mdlext-js-ripple-effect mdlext-js-animation-effect mdlext-light-color-theme"
+        role="tablist" aria-multiselectable="true">
+
+      <li class="mdlext-accordion__panel" role="presentation">
+        <header class="mdlext-accordion__tab" aria-expanded="true" role="tab">
+          <i class="material-icons">info</i>
+          <span class="mdlext-accordion__tab__caption">First section. A long caption should not push the state icon</span>
+          <i class="mdlext-aria-toggle-material-icons"></i>
+        </header>
+        <section class="mdlext-accordion__tabpanel" role="tabpanel" aria-hidden="false">
+          <h5>Content #1 goes here</h5>
+          <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam tristique eget augue eget gravida.
+            Etiam eget imperdiet massa. Aliquam nisi eros, molestie a vulputate quis, tempor nec quam. Ut at libero
+            in sem pellentesque imperdiet. Praesent pretium, sapien vel mollis porttitor, felis magna vehicula metus,
+            ac dignissim odio tortor nec quam.Fusce tincidunt leo in est <a href="#">venenatis porta</a>.
+          </p>
+          <p>Maecenas eu vestibulum orci. Ut eget nisi a est sagittis euismod a vel
+            justo. Quisque at dui urna. Duis vel velit leo. Nulla nunc sem, rutrum at aliquet in, aliquet id velit. Duis
+            mattis placerat erat, a aliquam leo rhoncus vel. Sed nec diam ex. Praesent convallis purus lorem, vel porttitor
+            neque gravida quis. Etiam et malesuada dui. Nunc vitae viverra dui. Suspendisse feugiat efficitur augue, quis
+            blandit leo ullamcorper vel.
+          </p>
+        </section>
+      </li>
+      <li class="mdlext-accordion__panel" role="presentation">
+        <header class="mdlext-accordion__tab" aria-expanded="false" role="tab">
+          <span class="mdlext-accordion__tab__caption">Tab #2</span>
+          <i class="mdlext-aria-toggle-material-icons"></i>
+        </header>
+        <section class="mdlext-accordion__tabpanel" role="tabpanel" hidden aria-hidden="true">
+          <h5>Content #2 goes here</h5>
+          <p>Curabitur malesuada placerat nunc, id dapibus justo tempor in. Ut molestie
+            arcu justo, id volutpat eros vestibulum eget. Fusce tincidunt leo in est venenatis porta.
+          </p>
+        </section>
+      </li>
+      <li class="mdlext-accordion__panel" role="presentation">
+        <header class="mdlext-accordion__tab" aria-expanded="false" role="tab" disabled tabindex="0">
+          <i class="material-icons">warning</i>
+          <span class="mdlext-accordion__tab__caption">Tab #3, disabled</span>
+          <i class="mdlext-aria-toggle-material-icons"></i>
+        </header>
+        <section class="mdlext-accordion__tabpanel" role="tabpanel" hidden aria-hidden="true">
+          <h5>Content #3 goes here</h5>
+          <p>Praesent pretium, sapien vel mollis porttitor, felis magna vehicula metus,
+            ac dignissim odio tortor nec quam. Nam molestie, arcu id maximus lacinia, ante ipsum posuere mauris, ac
+            maximus massa felis quis quam. usce tincidunt leo in est venenatis porta.
+          </p>
+        </section>
+      </li>
+      <li class="mdlext-accordion__panel" role="presentation">
+        <header class="mdlext-accordion__tab" aria-expanded="false" role="tab">
+          <i class="material-icons">accessibility</i>
+          <i class="material-icons">help_outline</i>
+          <i class="material-icons">radio</i>
+          <span class="mdlext-accordion__tab__caption">Tab #4, no toggle icon</span>
+        </header>
+        <section class="mdlext-accordion__tabpanel" role="tabpanel" hidden aria-hidden="true">
+          <h5>Content #4 goes here</h5>
+          <p>Praesent pretium, sapien vel mollis porttitor, felis magna vehicula metus,
+            ac dignissim odio tortor nec quam. Nam molestie, arcu id maximus lacinia, ante ipsum posuere mauris, ac
+            maximus massa felis quis quam. usce tincidunt leo in est venenatis porta.
+          </p>
+        </section>
+      </li>
+      <li class="mdlext-accordion__panel" role="presentation">
+        <header class="mdlext-accordion__tab" role="tab">
+          <button class="mdl-button mdl-button--icon mdl-button--colored"><i class="material-icons">favorite</i></button>
+          <button class="mdl-button mdl-button--icon mdl-button--colored"><i class="material-icons">share</i></button>
+          <span class="mdlext-accordion__tab__caption">Tab #5, with icon buttons</span>
+          <i class="mdlext-aria-toggle-material-icons"></i>
+        </header>
+        <section class="mdlext-accordion__tabpanel" role="tabpanel">
+          <h5>Content #5 goes here</h5>
+          <p>Praesent pretium, sapien vel mollis porttitor, felis magna vehicula metus,
+            ac dignissim odio tortor nec quam. Nam molestie, arcu id maximus lacinia, ante ipsum posuere mauris, ac
+            maximus massa felis quis quam. usce tincidunt leo in est venenatis porta.
+          </p>
+        </section>
+      </li>
+    </ul>
+  </div>  <!-- mdl-cell -->
+</div> <!-- mdl-grid -->
+
+
+
+<p class="mdl-typography--caption" style="margin-top: 64px;">
+  All images appearing in this page are the exclusive property of Leif Olsen and are protected under the United States and International Copyright laws.
+  The images may not be reproduced or manipulated without the written permission of Leif Olsen.
+  Use of any image as the basis for another photographic concept or illustration (digital, artist rendering or alike) is a violation of the United States and International Copyright laws.
+  All images are copyrighted &copy; Leif Olsen, 2016.
+</p>
+
+<script>
+  (function() {
+    'use strict';
+
+    function insertPanel() {
+      var panel =
+        '<li class="mdlext-accordion__panel">'
+        +  '<header class="mdlext-accordion__tab" aria-expanded="true">'
+        +    '<span class="mdlext-accordion__tab__caption">New Tab</span>'
+        +    '<i class="mdlext-aria-toggle-material-icons"></i>'
+        +  '</header>'
+        +  '<section class="mdlext-accordion__tabpanel">'
+        +    '<h5>New tab content</h5>'
+        +    '<p>Curabitur malesuada placerat nunc, id dapibus justo tempor in. Ut molestie'
+        +      'arcu justo, id volutpat eros vestibulum eget. Fusce tincidunt leo in est venenatis porta.'
+        +    '</p>'
+        +  '</section>'
+        +'</li>';
+
+      var accordion = document.querySelector('#demo-accordion-6');
+      accordion.insertAdjacentHTML('beforeend', panel);
+    }
+
+    window.addEventListener('load', function() {
+
+      // Listen to accordion toggle event
+      document.querySelector('#demo-accordion-6').addEventListener('toggle', function(e) {
+        //console.log('Accordion tab toggled. New state:', e.detail.state, 'Tab:', e.detail.tab, 'Tabpanel:', e.detail.tabpanel);
+        console.log('Accordion tab toggled. New state:', e.detail.state);
+      });
+
+      // Interact with accordion using public methods
+      document.querySelector('#btn-api-expand-all').addEventListener('click', function(e) {
+        var accordion = document.querySelector('#demo-accordion-6');
+        accordion.MaterialExtAccordion.command( {action: 'open'} );
+      });
+
+      document.querySelector('#btn-api-collapse-all').addEventListener('click', function(e) {
+        var accordion = document.querySelector('#demo-accordion-6');
+        accordion.MaterialExtAccordion.command( {action: 'close'} );
+      });
+
+      document.querySelector('#btn-api-open-tab2').addEventListener('click', function(e) {
+        var accordion = document.querySelector('#demo-accordion-6');
+        var tab2 = document.querySelector('#demo-accordion-6 .mdlext-accordion__panel:nth-child(2) .mdlext-accordion__tab');
+        accordion.MaterialExtAccordion.command( {action: 'open', target: tab2} );
+      });
+
+      document.querySelector('#btn-api-close-tab2').addEventListener('click', function(e) {
+        var accordion = document.querySelector('#demo-accordion-6');
+        var tab2 = document.querySelector('#demo-accordion-6 .mdlext-accordion__panel:nth-child(2)');
+        accordion.MaterialExtAccordion.command( {action: 'close', target: tab2} );
+      });
+
+      document.querySelector('#btn-api-toggle-tab2').addEventListener('click', function(e) {
+        var accordion = document.querySelector('#demo-accordion-6');
+        var tab2 = document.querySelector('#demo-accordion-6 .mdlext-accordion__panel:nth-child(2)');
+        accordion.MaterialExtAccordion.command( {action: 'toggle', target: tab2} );
+      });
+
+      document.querySelector('#btn-api-new-tab').addEventListener('click', function(e) {
+        insertPanel();
+        var accordion = document.querySelector('#demo-accordion-6');
+        var panelElement  = document.querySelector('#demo-accordion-6 .mdlext-accordion__panel:last-child');
+        accordion.MaterialExtAccordion.command( {action: 'upgrade', target: panelElement} );
+      });
+
+      // Interact with accordion using custom event
+      var eventButtons = document.querySelectorAll('button[id^="btn-event-"]');
+      for (var i = 0, n = eventButtons.length; i < n; i++) {
+        eventButtons[i].addEventListener('click', function(e) {
+          var ce;
+          var tab2 = document.querySelector('#demo-accordion-6 .mdlext-accordion__panel:nth-child(2)');
+
+          switch (e.target.id) {
+            case 'btn-event-expand-all':
+              ce = new CustomEvent('command', { detail: { action : 'open' } });
+              break;
+            case 'btn-event-collapse-all':
+              ce = new CustomEvent('command', { detail: { action : 'close' } });
+              break;
+            case 'btn-event-open-tab2':
+              ce = new CustomEvent('command', { detail: { action : 'open', target: tab2 } });
+              break;
+            case 'btn-event-close-tab2':
+              ce = new CustomEvent('command', { detail: { action : 'close', target: tab2 } });
+              break;
+            case 'btn-event-toggle-tab2':
+              ce = new CustomEvent('command', { detail: { action : 'toggle', target: tab2 } });
+              break;
+            case 'btn-event-new-tab':
+              insertPanel();
+              var panelElement  = document.querySelector('#demo-accordion-6 .mdlext-accordion__panel:last-child');
+              ce = new CustomEvent('command', { detail: { action : 'upgrade', target: panelElement } });
+              break;
+            default:
+              return;
+          }
+          var accordion = document.querySelector('#demo-accordion-6');
+          accordion.dispatchEvent(ce);
+        });
+      }
+    });
+
+  }());
+
+</script>
diff --git a/node_modules/mdl-ext/src/aria-expanded-toggle/_aria-expanded-toggle.scss b/node_modules/mdl-ext/src/aria-expanded-toggle/_aria-expanded-toggle.scss
new file mode 100644
index 0000000..1f23b26
--- /dev/null
+++ b/node_modules/mdl-ext/src/aria-expanded-toggle/_aria-expanded-toggle.scss
@@ -0,0 +1,31 @@
+@charset "UTF-8";
+
+/**
+ * @license
+ * Copyright 2016-2017 Leif Olsen. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * This code is built with Google Material Design Lite,
+ * which is Licensed under the Apache License, Version 2.0
+ */
+
+@import "../mixins";
+
+.mdlext-aria-expanded-plus-minus {
+  @include mdlext-aria-expanded-toggle($font-family: inherit);
+}
+
+.mdlext-aria-expanded-more-less {
+  @include mdlext-aria-expanded-toggle($icon: 'expand_more', $icon-expanded: 'expand_less');
+}
diff --git a/node_modules/mdl-ext/src/bordered-fields/_bordered-fields.scss b/node_modules/mdl-ext/src/bordered-fields/_bordered-fields.scss
new file mode 100644
index 0000000..286e44a
--- /dev/null
+++ b/node_modules/mdl-ext/src/bordered-fields/_bordered-fields.scss
@@ -0,0 +1,251 @@
+/**
+ * Copyright 2016 Leif Olsen. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * The bordered fields are based on / inspired by this CodePen: http://codepen.io/prajwal078/pen/LVJZXz?editors=010
+ */
+
+// Use of this module requires the user to include variables from material-design-lite
+//@import "../../node_modules/material-design-lite/src/variables";
+//@import "../../node_modules/material-design-lite/src/mixins";
+
+@import "../variables";
+@import "../functions";
+
+
+// "Theme" for this styling
+.mdlext-bordered-fields {
+  box-sizing: border-box;
+
+  * {
+    box-sizing: border-box;
+  }
+
+  // Styling for textfield and selectfield.
+  .mdl-textfield,
+  .mdlext-selectfield {
+    padding: 0;
+    margin: $mdlext-bordered-field-vertical-spacing-top 0 $mdlext-bordered-field-vertical-spacing-bottom 0;
+
+    .mdl-textfield__input,
+    .mdlext-selectfield__select {
+      height: $mdlext-bordered-field-height;
+      background-color: $mdlext-bordered-field-background-color;
+      border: $mdlext-bordered-field-border-width solid $mdlext-bordered-field-border-color;
+      border-radius: $mdlext-bordered-field-border-radius;
+      padding: $mdlext-bordered-field-padding-top $mdlext-bordered-field-padding $mdlext-bordered-field-padding-bottom $mdlext-bordered-field-padding;
+      font-size: $mdlext-bordered-field-input-text-font-size;
+      font-weight: $mdlext-bordered-field-font-weight;
+      color: $mdlext-bordered-field-input-text-color;
+
+      &:disabled {
+        color: $mdlext-bordered-field-input-text-disabled-text-color;
+        background-color: $mdlext-bordered-field-disabled-background-color;
+        border-color: $mdlext-bordered-field-disabled-border-color;
+      }
+
+      // MDL can not handle required attribute properly. Planned for MDL-v2
+      //&:required {
+      //  background-color: $mdlext-bordered-field-required-background-color;
+      //  border-color: $mdlext-bordered-field-required-border-color;
+      //}
+
+      &:focus {
+        background-color: $mdlext-bordered-field-focus-background-color;
+        border-color: $mdlext-bordered-field-focus-border-color;
+      }
+
+      // MDL can not handle required. Planned for MDL-v2
+      //&:required:focus {
+      //  background-color: $mdlext-bordered-field-required-focus-background-color;
+      //  border-color: $mdlext-bordered-field-required-focus-border-color;
+      //}
+    }
+    .mdlext-selectfield__select {
+      padding-right: calc(1em + #{$mdlext-bordered-field-padding});  // space for down arrow
+    }
+
+    /*
+    &.is-dirty {
+      .mdl-textfield__input,
+      .mdlext-selectfield__select {
+      }
+    }
+    */
+
+    &.is-invalid {
+      .mdl-textfield__input,
+      .mdlext-selectfield__select {
+        color: $mdlext-bordered-field-input-text-error-color;
+        border-color: $mdlext-bordered-field-error-border-color;
+        background-color: $mdlext-bordered-field-error-background-color;
+
+        &:focus {
+          //&:required:focus {
+          border-color: $mdlext-bordered-field-error-focus-border-color;
+          background-color: $mdlext-bordered-field-error-focus-background-color;
+        }
+      }
+    }
+  }
+
+  .mdlext-selectfield::after {
+    top: auto;
+    bottom: $mdlext-bordered-field-padding-bottom;  // Position of down arrow
+  }
+
+  fieldset[disabled] .mdlext-selectfield::after,
+  .mdlext-selectfield.is-disabled::after {
+    color: $mdlext-bordered-field-input-text-disabled-text-color;
+    @include mdlext-arrow(bottom, $mdlext-selectfield-arrow-width, $mdlext-selectfield-arrow-length, $mdlext-bordered-field-input-text-disabled-text-color);
+  }
+
+
+  fieldset[disabled] .mdl-textfield .mdl-textfield__input,
+  fieldset[disabled] .mdlext-selectfield .mdlext-selectfield__select {
+    color: $mdlext-bordered-field-input-text-disabled-text-color;
+    background-color: $mdlext-bordered-field-disabled-background-color;
+    border-color: $mdlext-bordered-field-disabled-border-color;
+  }
+
+
+  // Styling for the label / floating label.
+  .mdl-textfield,
+  .mdlext-selectfield {
+
+    &.is-dirty,
+    &.has-placeholder {
+      .mdl-textfield__label,
+      .mdlext-selectfield__label {
+        visibility: hidden;
+      }
+    }
+    .mdl-textfield__label,
+    .mdlext-selectfield__label {
+      color: $mdlext-bordered-field-input-text-label-color;
+      font-size: $mdlext-bordered-field-label-font-size;
+      font-weight: $mdlext-bordered-field-font-weight;
+      padding-left: $mdlext-bordered-field-padding;
+      top: auto;
+      bottom: $mdlext-bordered-field-padding-bottom;
+
+      // Hides the colored underline for the textField/selectfield.
+      &::after {
+        background-color: transparent !important;
+        visibility: hidden !important;
+      }
+    }
+    &.mdl-textfield--floating-label.is-focused.is-focused,
+    &.mdl-textfield--floating-label.is-dirty.is-dirty,
+    &.mdl-textfield--floating-label.has-placeholder,
+    &.mdlext-selectfield--floating-label.is-focused.is-focused,
+    &.mdlext-selectfield--floating-label.is-dirty.is-dirty,
+    &.mdlext-selectfield--floating-label.has-placeholder {
+
+      .mdl-textfield__label,
+      .mdlext-selectfield__label {
+        color: $mdlext-bordered-field-input-text-label-focus-color;
+        font-size: $mdlext-bordered-field-floating-label-font-size;
+        font-weight: $mdlext-bordered-field-floating-label-font-weight;
+        top: auto;
+        bottom: $mdlext-bordered-field-floating-label-focus-bottom;
+        visibility: visible;
+      }
+    }
+    &.mdl-textfield--floating-label.is-disabled.is-disabled,
+    &.mdlext-selectfield--floating-label.is-disabled.is-disabled {
+
+      .mdl-textfield__label,
+      .mdlext-selectfield__label {
+        color: $mdlext-bordered-field-input-text-label-disabled-color;
+      }
+    }
+    &.mdl-textfield--floating-label.is-invalid.is-invalid,
+    &.mdlext-selectfield--floating-label.is-invalid.is-invalid {
+
+      .mdl-textfield__label,
+      .mdlext-selectfield__label {
+        color: $mdlext-bordered-field-input-text-label-error-color;
+      }
+    }
+  }
+
+  fieldset[disabled] .mdl-textfield .mdl-textfield__label,
+  fieldset[disabled] .mdl-selectfield .mdl-selectfield__label {
+    color: $mdlext-bordered-field-input-text-label-disabled-color;
+  }
+
+  // Icon(s) and/or button(s) inside textfield
+  .mdl-textfield,
+  .mdlext-selectfield {
+    &.mdlext-bordered-fields__icon-left,
+    &.mdlext-bordered-fields__icon-right {
+      & > i,
+      & > .mdl-button {
+        position: absolute;
+        bottom: $mdlext-bordered-field-padding-bottom - 2px;
+      }
+      & > i {
+        bottom: $mdlext-bordered-field-padding-bottom + 2px;
+      }
+    }
+    &.mdlext-bordered-fields__icon-left {
+      & > i:first-child,
+      & > .mdl-button:first-child {
+        left: $mdlext-bordered-field-padding/2;
+      }
+      & > i ~ .mdl-textfield__input,
+      & > .mdl-button ~ .mdl-textfield__input,
+      & > i ~ .mdlext-selectfield__select,
+      & > .mdl-button ~ .mdlext-selectfield__select {
+        padding-left: $input-text-button-size;
+      }
+      & > i ~ .mdl-textfield__label,
+      & > .mdl-button ~ .mdl-textfield__label {
+        left: $input-text-button-size - $mdlext-bordered-field-padding;
+      }
+      & > i ~ .mdlext-selectfield__label,
+      & > .mdl-button ~ .mdlext-selectfield__label {
+        left: $input-text-button-size - $mdlext-bordered-field-padding;
+      }
+    }
+    &.mdlext-bordered-fields__icon-right {
+      & > .mdl-textfield__input {
+        padding-right: $input-text-button-size;
+      }
+      & > i:last-child,
+      & > .mdl-button:last-child {
+        left: auto;
+        right: $mdlext-bordered-field-padding/2;
+      }
+    }
+    &.is-disabled i,
+    &.is-disabled .mdl-button {
+      color: $mdlext-bordered-field-disabled-border-color;
+      pointer-events: none;
+    }
+  }
+
+  fieldset[disabled] .mdl-textfield,
+  fieldset[disabled] .mdlext-selectfield {
+    i,
+    .mdl-button {
+      color: $mdlext-bordered-field-disabled-border-color;
+      pointer-events: none;
+    }
+  }
+}
+
diff --git a/node_modules/mdl-ext/src/bordered-fields/readme.md b/node_modules/mdl-ext/src/bordered-fields/readme.md
new file mode 100644
index 0000000..40dcfff
--- /dev/null
+++ b/node_modules/mdl-ext/src/bordered-fields/readme.md
@@ -0,0 +1,98 @@
+# Bordered fields
+![Bordered fields](../../etc/bordered-fields-theme.png)
+
+Demonstrates how you can create your own theme of MDL text fields.
+
+## Introduction
+The Material Design Lite Ext (MDLEXT) bordered fields component is a method for decorating contained
+MDL textfields and MDLEXT selectfields without affecting the original MDL design. You can apply the `mdlext-bordered-fields` class
+to any HTML block element and use that as a container for the bordered fields.
+
+### To include a MDLEXT **bordered fields** component:
+&nbsp;1. Code a block element, as the "outer" container, intended to hold all of the bordered fields.
+```html
+<div>
+</div>
+```
+
+&nbsp;2. Add the `mdlext-bordered-fields` MDLEXT class to the block element using the `class` attribute.
+```html
+<div class="mdlext-bordered-fields">
+</div>
+```
+
+&nbsp;3. Add the MDL and MDLEXT fields you want to decorate.
+```html
+<div class="mdlext-bordered-fields">
+  <div class="mdl-textfield mdl-js-textfield">
+    <input class="mdl-textfield__input" type="text" id="sample1">
+    <label class="mdl-textfield__label" for="sample1">Text ...</label>
+  </div>
+
+  <div class="mdlext-selectfield mdlext-js-selectfield">
+    <select class="mdlext-selectfield__select" id="nordic-countries" name="nordic-countries">
+      <option value=""></option>
+      <option value="option1">Norway</option>
+      <option value="option2">Sweden</option>
+      <option value="option3">Suomi</option>
+      <option value="option4">Denmark</option>
+      <option value="option5">Iceland</option>
+    </select>
+    <label class="mdlext-selectfield__label" for="nordic-countries">Where do you want to go</label>
+  </div>
+  .....
+</div>
+```
+
+&nbsp;4. Optionally embed icons and/or buttons into a bordered field by adding the CSS classes 
+`mdlext-bordered-fields__icon-left` and `mdlext-bordered-fields__icon-right` respectively.
+```html
+  <div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label mdlext-bordered-fields__icon-left mdlext-bordered-fields__icon-right">
+    <i class="material-icons">radio</i>
+    <input class="mdl-textfield__input" type="text" id="icon-button1">
+    <label class="mdl-textfield__label">Text...</label>
+    <label class="mdl-button mdl-js-button mdl-button--icon" for="icon-button1">
+      <i class="material-icons">settings_voice</i>
+    </label>
+  </div>
+  
+  <div class="mdlext-selectfield mdlext-js-selectfield mdlext-bordered-fields__icon-left">
+    <i class="material-icons">radio</i>
+    <select class="mdlext-selectfield__select" id="nordic-countries" name="nordic-countries">
+      <option value=""></option>
+      <option value="option1">Norway</option>
+      <option value="option2">Sweden</option>
+      <option value="option3">Suomi</option>
+      <option value="option4">Denmark</option>
+      <option value="option5">Iceland</option>
+    </select>
+    <label class="mdlext-selectfield__label" for="nordic-countries">Where do you want to go</label>
+  </div>
+```
+
+>**Note:** The `mdlext-selectfield` component can only embed an icon at the left hand side.
+
+#### Examples
+See the [example code](./snippets/bordered-fields.html).
+
+## Configuration options
+
+The MDLEXT CSS classes apply various predefined visual and behavioral enhancements to text fields and select fields. 
+The table below lists the available classes and their effects.
+
+| MDLEXT class | Effect | Remarks |
+|-----------|--------|---------|
+| `mdlext-bordered-fields` | Defines container as an MDL bordered fields component | Required on an "outer" block element|
+| `mdlext-bordered-fields__icon-left` | Add class on `mdl-textfield` or `mdlext-selectfield` container if you want to embedd a left aligned icon or a button into the bordered field |  |
+| `mdlext-bordered-fields__icon-right` | Add class on `mdl-textfield` or `mdlext-selectfield` container if you want to embedd a right aligned icon or a button into the bordered field  |  |
+
+
+### SASS variables.
+
+See: [variables.scss](../_variables.scss)
+
+### Calculations of heights, vertical spacing and positioning of labels and icons
+See: [bordered-fields.scss](./_bordered-fields.scss)
+
+### Credits 
+The Bordered Fields component is based on this [CodePen](http://codepen.io/prajwal078/pen/LVJZXz)
diff --git a/node_modules/mdl-ext/src/bordered-fields/snippets/bordered-fields.html b/node_modules/mdl-ext/src/bordered-fields/snippets/bordered-fields.html
new file mode 100644
index 0000000..5b14918
--- /dev/null
+++ b/node_modules/mdl-ext/src/bordered-fields/snippets/bordered-fields.html
@@ -0,0 +1,376 @@
+<p>Demonstrates how you can create your own theme of MDL text fields without affecting the original MDL fields.</p>
+
+<style>
+  .borderedfield-demo-container {
+  }
+
+  .borderedfield-demo-container .mdl-cell {
+    padding: 0 4px 8px 0;
+  }
+
+  .borderedfield-demo-container .mdl-cell p {
+    margin-bottom: 0;
+    white-space: nowrap;
+    text-overflow: ellipsis;
+    overflow: hidden;
+  }
+
+  /* File input example */
+  .mdl-button--file input {
+    cursor: pointer;
+    opacity: 0;
+    width: 1px;
+    height: 1px;
+  }
+</style>
+
+
+<div class = "borderedfield-demo-container mdlext-bordered-fields">
+
+  <div class="mdl-grid mdl-grid--no-spacing">
+
+    <div class="mdl-cell mdl-cell--4-col">
+      <p>Text</p>
+      <div class="mdl-textfield mdl-js-textfield">
+        <input class="mdl-textfield__input" type="text">
+        <label class="mdl-textfield__label">Text...</label>
+      </div>
+    </div>
+
+    <div class="mdl-cell mdl-cell--4-col">
+      <p>Text numeric</p>
+      <div class="mdl-textfield mdl-js-textfield">
+        <input class="mdl-textfield__input" type="text" pattern="-?[0-9]*(\.[0-9]+)?">
+        <label class="mdl-textfield__label">Number...</label>
+        <span class="mdl-textfield__error">Input is not a number!</span>
+      </div>
+    </div>
+
+
+    <div class="mdl-cell mdl-cell--4-col">
+      <p>Text with floating label, required field</p>
+      <div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label">
+        <input class="mdl-textfield__input" type="text" list="languages" placeholder="Select a language" required>
+        <label class="mdl-textfield__label">Programming language</label>
+      </div>
+    </div>
+    <datalist id="languages">
+      <option value="HTML">
+      <option value="CSS">
+      <option value="JavaScript">
+      <option value="Java">
+      <option value="Ruby">
+      <option value="PHP">
+      <option value="Go">
+      <option value="Erlang">
+      <option value="Python">
+      <option value="C">
+      <option value="C#">
+      <option value="C++">
+    </datalist>
+
+    <div class="mdl-cell mdl-cell--4-col">
+      <p>Select element with floating label</p>
+      <div class="mdlext-selectfield mdlext-js-selectfield mdlext-selectfield--floating-label">
+        <select class="mdlext-selectfield__select">
+          <option value=""></option>
+          <option value="option1">option 1</option>
+          <option value="option2">option 2</option>
+          <option value="option3">option 3</option>
+          <option value="option4">option 4</option>
+          <option value="option5">option 5</option>
+          <option value="option6">option 5 abcdefghijklmnopqrstuvw0123456789</option>
+        </select>
+        <label class="mdlext-selectfield__label">Profession</label>
+      </div>
+    </div>
+
+    <div class="mdl-cell mdl-cell--4-col">
+      <p>Numeric with floating label</p>
+      <div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label">
+        <input class="mdl-textfield__input" type="text" pattern="-?[0-9]*(\.[0-9]+)?">
+        <label class="mdl-textfield__label">Number...</label>
+        <span class="mdl-textfield__error">Input is not a number!</span>
+      </div>
+    </div>
+
+    <div class="mdl-cell mdl-cell--4-col">
+      <p>Disabled floating label</p>
+      <div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label">
+        <input class="mdl-textfield__input" type="text" pattern="-?[0-9]*(\.[0-9]+)?" disabled value="123">
+        <label class="mdl-textfield__label" >Number...</label>
+        <span class="mdl-textfield__error">Input is not a number!</span>
+      </div>
+    </div>
+
+    <div class="mdl-cell mdl-cell--4-col">
+      <p>Text with icons left and right, disabled</p>
+      <div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label mdlext-bordered-fields__icon-left mdlext-bordered-fields__icon-right">
+        <i class="material-icons">radio</i>
+        <input class="mdl-textfield__input" type="text" disabled>
+        <label class="mdl-textfield__label">Text...</label>
+        <i class="material-icons">fingerprint</i>
+      </div>
+    </div>
+
+
+    <div class="mdl-cell mdl-cell--4-col">
+      <p>Text with button left</p>
+      <div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label mdlext-bordered-fields__icon-left">
+        <label class="mdl-button mdl-js-button mdl-button--icon">
+          <i class="material-icons">phone</i>
+        </label>
+
+        <input class="mdl-textfield__input" type="text">
+        <label class="mdl-textfield__label">Text...</label>
+      </div>
+    </div>
+
+    <div class="mdl-cell mdl-cell--4-col">
+      <p>Text with button right</p>
+      <div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label mdlext-bordered-fields__icon-right">
+        <input class="mdl-textfield__input" type="text">
+        <label class="mdl-textfield__label">Text...</label>
+
+        <label class="mdl-button mdl-js-button mdl-button--icon">
+          <i class="material-icons">settings_voice</i>
+        </label>
+      </div>
+    </div>
+
+
+    <div class="mdl-cell mdl-cell--4-col">
+      <p>Select element</p>
+      <div class="mdlext-selectfield mdlext-js-selectfield">
+        <select class="mdlext-selectfield__select">
+          <option value=""></option>
+          <option value="option1">option 1</option>
+          <option value="option2">option 2</option>
+          <option value="option3">option 3</option>
+          <option value="option4">option 4</option>
+          <option value="option5">option 5</option>
+          <option value="option6">option 5 abcdefghijklmnopqrstuvw0123456789</option>
+        </select>
+        <label class="mdlext-selectfield__label">Profession</label>
+      </div>
+    </div>
+
+    <div class="mdl-cell mdl-cell--4-col">
+      <p>Select element with floating label</p>
+      <div class="mdlext-selectfield mdlext-js-selectfield mdlext-selectfield--floating-label">
+        <select class="mdlext-selectfield__select">
+          <option value=""></option>
+          <option value="option1">option 1</option>
+          <option value="option2">option 2</option>
+          <option value="option3">option 3</option>
+          <option value="option4">option 4</option>
+          <option value="option5">option 5</option>
+        </select>
+        <label class="mdlext-selectfield__label">Profession</label>
+      </div>
+    </div>
+
+    <div class="mdl-cell mdl-cell--4-col">
+      <p>Disabled Select element</p>
+      <div class="mdlext-selectfield mdlext-js-selectfield mdlext-selectfield--floating-label">
+        <select class="mdlext-selectfield__select" disabled>
+          <option value=""></option>
+          <option value="option1">option 1</option>
+          <option value="option2">option 2</option>
+          <option value="option3">option 3</option>
+          <option value="option4">option 4</option>
+          <option value="option5">option 5</option>
+        </select>
+        <label class="mdlext-selectfield__label">Profession</label>
+      </div>
+    </div>
+
+    <div class="mdl-cell mdl-cell--4-col">
+      <p>Select element with icon left</p>
+      <div class="mdlext-selectfield mdlext-js-selectfield mdlext-bordered-fields__icon-left">
+        <i class="material-icons">radio</i>
+        <select class="mdlext-selectfield__select">
+          <option value=""></option>
+          <option value="option1">option 1</option>
+          <option value="option2">option 2</option>
+          <option value="option3">option 3</option>
+          <option value="option4">option 4</option>
+          <option value="option5">option 5</option>
+        </select>
+        <label class="mdlext-selectfield__label">Profession</label>
+      </div>
+    </div>
+
+    <div class="mdl-cell mdl-cell--4-col">
+      <p>Select element with button left</p>
+      <div class="mdlext-selectfield mdlext-js-selectfield mdlext-selectfield--floating-label mdlext-bordered-fields__icon-left">
+        <label class="mdl-button mdl-js-button mdl-button--icon">
+          <i class="material-icons">phone</i>
+        </label>
+        <select class="mdlext-selectfield__select">
+          <option value=""></option>
+          <option value="option1">option 1</option>
+          <option value="option2">option 2</option>
+          <option value="option3">option 3</option>
+          <option value="option4">option 4</option>
+          <option value="option5">option 5</option>
+        </select>
+        <label class="mdlext-selectfield__label">Profession</label>
+      </div>
+    </div>
+
+    <div class="mdl-cell mdl-cell--4-col">
+      <p>Disabled Select element</p>
+      <div class="mdlext-selectfield mdlext-js-selectfield mdlext-selectfield--floating-label mdlext-bordered-fields__icon-left">
+        <label class="mdl-button mdl-js-button mdl-button--icon">
+          <i class="material-icons">phone</i>
+        </label>
+        <select class="mdlext-selectfield__select" disabled>
+          <option value=""></option>
+          <option value="option1">option 1</option>
+          <option value="option2">option 2</option>
+          <option value="option3">option 3</option>
+          <option value="option4">option 4</option>
+          <option value="option5">option 5</option>
+        </select>
+        <label class="mdlext-selectfield__label">Profession</label>
+      </div>
+    </div>
+
+
+
+    <div class="mdl-cell mdl-cell--4-col">
+      <p>Text with icon left</p>
+      <div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label mdlext-bordered-fields__icon-left">
+        <i class="material-icons">radio</i>
+        <input class="mdl-textfield__input" type="text">
+        <label class="mdl-textfield__label">Text...</label>
+      </div>
+    </div>
+
+    <div class="mdl-cell mdl-cell--4-col">
+      <p>Text with icon right</p>
+      <div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label mdlext-bordered-fields__icon-right">
+        <input class="mdl-textfield__input" type="text">
+        <label class="mdl-textfield__label">Text...</label>
+        <i class="material-icons">fingerprint</i>
+      </div>
+    </div>
+
+    <div class="mdl-cell mdl-cell--4-col">
+      <p>Text with icons left and right</p>
+      <div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label mdlext-bordered-fields__icon-left mdlext-bordered-fields__icon-right">
+        <i class="material-icons">radio</i>
+        <input class="mdl-textfield__input" type="text">
+        <label class="mdl-textfield__label">Text...</label>
+        <i class="material-icons">fingerprint</i>
+      </div>
+    </div>
+
+    <div class="mdl-cell mdl-cell--4-col">
+      <p>Text with buttons left and right</p>
+      <div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label mdlext-bordered-fields__icon-left mdlext-bordered-fields__icon-right">
+        <label class="mdl-button mdl-js-button mdl-button--icon">
+          <i class="material-icons">phone</i>
+        </label>
+
+        <input class="mdl-textfield__input" type="text">
+        <label class="mdl-textfield__label">Text...</label>
+
+        <label class="mdl-button mdl-js-button mdl-button--icon">
+          <i class="material-icons">settings_voice</i>
+        </label>
+      </div>
+    </div>
+
+    <div class="mdl-cell mdl-cell--4-col">
+      <p>Text with buttons left and right, disabled</p>
+      <div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label mdlext-bordered-fields__icon-left mdlext-bordered-fields__icon-right">
+        <label class="mdl-button mdl-js-button mdl-button--icon">
+          <i class="material-icons">phone</i>
+        </label>
+
+        <input class="mdl-textfield__input" type="text" disabled>
+        <label class="mdl-textfield__label">Text...</label>
+
+        <label class="mdl-button mdl-js-button mdl-button--icon">
+          <i class="material-icons">settings_voice</i>
+        </label>
+      </div>
+    </div>
+
+    <div class="mdl-cell mdl-cell--4-col">
+      <p>Text with icon and button</p>
+      <div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label mdlext-bordered-fields__icon-left mdlext-bordered-fields__icon-right">
+        <i class="material-icons">radio</i>
+        <input class="mdl-textfield__input" type="text">
+        <label class="mdl-textfield__label">Text...</label>
+        <label class="mdl-button mdl-js-button mdl-button--icon">
+          <i class="material-icons">settings_voice</i>
+        </label>
+      </div>
+    </div>
+
+    <div class="mdl-cell mdl-cell--4-col">
+      <p>File upload</p>
+      <div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label mdlext-bordered-fields__icon-right ">
+        <input class="mdl-textfield__input" type="text" id="uploadfile2" readonly>
+        <label class="mdl-textfield__label">File (work in progress)</label>
+
+        <label class="mdl-button mdl-js-button mdl-button--primary mdl-button--icon mdl-button--file" for="uploadfile2">
+          <i class="material-icons">attach_file</i>
+          <input type="file" id="uploadBtn2">
+        </label>
+      </div>
+      <!--
+        // Need a script to work properly - something like this
+      -->
+      <script>
+        (function() {
+          'use strict';
+          document.querySelector('#uploadBtn2').addEventListener('change', function() {
+            var n = document.querySelector("#uploadfile2");
+            n.value = this.files[0].name;
+            n.parentNode.classList.add('is-dirty');
+          });
+        }());
+      </script>
+    </div>
+
+  </div>
+
+  <fieldset disabled>
+    <legend>Disabled fieldset</legend>
+    <div class="mdlext-selectfield mdlext-js-selectfield mdlext-selectfield--floating-label">
+      <select class="mdlext-selectfield__select">
+        <option value=""></option>
+        <option value="option1">option 1</option>
+        <option value="option2">option 2</option>
+        <option value="option3">option 3</option>
+        <option value="option4">option 4</option>
+        <option value="option5">option 5</option>
+        <option value="option6">option 5 abcdefghijklmnopqrstuvw0123456789</option>
+      </select>
+      <label class="mdlext-selectfield__label">Profession</label>
+    </div>
+
+    <div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label">
+      <input class="mdl-textfield__input" type="text" pattern="-?[0-9]*(\.[0-9]+)?">
+      <label class="mdl-textfield__label">Number...</label>
+      <span class="mdl-textfield__error">Input is not a number!</span>
+    </div>
+
+    <div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label mdlext-bordered-fields__icon-left mdlext-bordered-fields__icon-right">
+      <i class="material-icons">radio</i>
+      <input class="mdl-textfield__input" type="text">
+      <label class="mdl-textfield__label">Text...</label>
+      <label class="mdl-button mdl-js-button mdl-button--icon">
+        <i class="material-icons">settings_voice</i>
+      </label>
+    </div>
+  </fieldset>
+
+</div>
+
+<h5>Credits</h5>
+<p>The Bordered Fields Theme component is based on this <a href="http://codepen.io/prajwal078/pen/LVJZXz" target="_blank">CodePen</a></p>
diff --git a/node_modules/mdl-ext/src/carousel/_carousel.scss b/node_modules/mdl-ext/src/carousel/_carousel.scss
new file mode 100644
index 0000000..674751a
--- /dev/null
+++ b/node_modules/mdl-ext/src/carousel/_carousel.scss
@@ -0,0 +1,141 @@
+@charset "UTF-8";
+
+/**
+ * Copyright 2016 Leif Olsen. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * A carousel ...
+ */
+
+// Use of this module requires the user to include variables from material-design-lite
+//@import "../../node_modules/material-design-lite/src/variables";
+//@import "../../node_modules/material-design-lite/src/mixins";
+
+ul.mdlext-carousel {
+  list-style: none;
+}
+
+.mdlext-carousel {
+  box-sizing: border-box;
+  margin: 0;
+  padding: 0;
+  overflow: hidden;
+  height: 100%;  // Use a container to constrain height and width
+  width: 100%;
+  display: block;
+  white-space: nowrap;
+  font-size: 0;
+  background-color: transparent;
+}
+
+.mdlext-carousel__slide {
+  box-sizing: border-box;
+  display: inline-block;
+  position: relative;
+  outline: 0;
+  margin: 0 $mdlext-carousel-slide-margin-horizontal;
+  padding:0;
+  height: 100%;
+  border-top: $mdlext-carousel-slide-border-top-width solid transparent; // Makes room for the animated select/focus line
+
+  //&:focus,
+  &[aria-selected],
+  &[aria-selected='true'] {
+    figcaption {
+      // As far as I can see there is no way to darken/lighten a text color
+      // defined by MDL, due to the "unqote" functions.
+      // So this is a hack
+      color: rgba(0, 0, 0, 1) !important;
+      background-color: rgba(255, 255, 255, 0.25);
+    }
+  }
+
+  &[aria-selected]::after,
+  &[aria-selected='true']::after {
+    height: $mdlext-carousel-slide-border-top-width;
+    width: 100%;
+    display: block;
+    content: ' ';
+    top: (-$mdlext-carousel-slide-border-top-width);
+    left: 0;
+    position: absolute;
+    background: $mdlext-carousel-slide-border-top-color;
+    animation: border-expand 0.2s cubic-bezier(0.4, 0.0, 0.4, 1) 0.01s alternate forwards;
+    transition: all 1s cubic-bezier(0.4, 0.0, 1, 1);
+  }
+
+
+  a {
+    text-decoration: none;
+  }
+
+  figure {
+    box-sizing: border-box;
+    position: relative;
+    height: 100%;
+    margin: 0;
+    padding: 0;
+
+    img {
+      box-sizing: border-box;
+      max-height: 100%;
+    }
+
+    figcaption {
+      box-sizing: border-box;
+      @include typo-caption($colorContrast: false, $usePreferred: true);
+
+      color: $mdlext-carousel-slide-figcaption-color;
+      position: absolute;
+      bottom: 0;
+      left: 0;
+      white-space: nowrap;
+      overflow: hidden;
+      max-width: 100%;
+      width: 100%;
+      text-align: center;
+      text-overflow: ellipsis;
+      padding: 4px 0;
+    }
+    &:hover {
+      figcaption {
+        // As far as I can see there is no way to darken/lighten a text color
+        // defined by MDL, due to the "unqote" functions.
+        // So this is a hack
+        color: rgba(0, 0, 0, 1) !important;
+        background-color: rgba(255, 255, 255, 0.25);
+      }
+    }
+  }
+
+  .mdlext-carousel__slide__ripple-container {
+    text-decoration: none;
+    display: block;
+    overflow: hidden;
+    position: absolute;
+    top: 0;
+    left: 0;
+    right: 0;
+    bottom: 0;
+    outline: 0;
+
+    & .mdl-ripple {
+      background: $mdlext-carousel-slide-ripple-color;
+    }
+  }
+}
+
+
diff --git a/node_modules/mdl-ext/src/carousel/carousel.js b/node_modules/mdl-ext/src/carousel/carousel.js
new file mode 100644
index 0000000..8fe59e1
--- /dev/null
+++ b/node_modules/mdl-ext/src/carousel/carousel.js
@@ -0,0 +1,726 @@
+/**
+ * @license
+ * Copyright 2016 Leif Olsen. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * This code is built with Google Material Design Lite,
+ * which is Licensed under the Apache License, Version 2.0
+ */
+
+/**
+ * Image carousel
+ */
+
+import intervalFunction from '../utils/interval-function';
+import { inOutQuintic } from '../utils/easing';
+import { jsonStringToObject} from '../utils/json-utils';
+import {
+  VK_TAB,
+  VK_ENTER,
+  VK_ESC,
+  VK_SPACE,
+  VK_PAGE_UP,
+  VK_PAGE_DOWN,
+  VK_END,
+  VK_HOME,
+  VK_ARROW_LEFT,
+  VK_ARROW_UP,
+  VK_ARROW_RIGHT,
+  VK_ARROW_DOWN,
+  IS_UPGRADED,
+  IS_FOCUSED,
+  MDL_RIPPLE,
+  MDL_RIPPLE_COMPONENT,
+  MDL_RIPPLE_EFFECT,
+  MDL_RIPPLE_EFFECT_IGNORE_EVENTS
+} from '../utils/constants';
+
+const MDL_RIPPLE_CONTAINER = 'mdlext-carousel__slide__ripple-container';
+
+
+(function() {
+  'use strict';
+
+  //const CAROUSEL = 'mdlext-carousel';
+  const SLIDE      = 'mdlext-carousel__slide';
+  const ROLE       = 'list';
+  const SLIDE_ROLE = 'listitem';
+
+
+  /**
+   * @constructor
+   * @param {Element} element The element that will be upgraded.
+   */
+  const MaterialExtCarousel = function MaterialExtCarousel(element) {
+    // Stores the element.
+    this.element_ = element;
+
+    // Default config
+    this.config_ = {
+      interactive  : true,
+      autostart    : false,
+      type         : 'slide',
+      interval     : 1000,
+      animationLoop: intervalFunction(1000)
+    };
+
+    this.scrollAnimation_ = intervalFunction(33);
+
+    // Initialize instance.
+    this.init();
+  };
+
+  window['MaterialExtCarousel'] = MaterialExtCarousel;
+
+
+  /**
+   * Start slideshow animation
+   * @private
+   */
+  MaterialExtCarousel.prototype.startSlideShow_ = function() {
+
+    const nextSlide = () => {
+      let slide = this.element_.querySelector(`.${SLIDE}[aria-selected]`);
+      if(slide) {
+        slide.removeAttribute('aria-selected');
+        slide = slide.nextElementSibling;
+      }
+      if(!slide) {
+        slide = this.element_.querySelector(`.${SLIDE}:first-child`);
+        this.animateScroll_(0);
+      }
+      if(slide) {
+        this.moveSlideIntoViewport_(slide);
+        slide.setAttribute('aria-selected', '');
+        this.emitSelectEvent_('next', null, slide);
+        return true;
+      }
+      return false;
+    };
+
+    const nextScroll = direction => {
+      let nextDirection = direction;
+
+      if('next' === direction &&  this.element_.scrollLeft === this.element_.scrollWidth - this.element_.clientWidth) {
+        nextDirection = 'prev';
+      }
+      else if(this.element_.scrollLeft === 0) {
+        nextDirection = 'next';
+      }
+      const x = 'next' === nextDirection
+        ?  Math.min(this.element_.scrollLeft + this.element_.clientWidth, this.element_.scrollWidth - this.element_.clientWidth)
+        :  Math.max(this.element_.scrollLeft - this.element_.clientWidth, 0);
+
+      this.animateScroll_(x, 1000);
+      return nextDirection;
+    };
+
+
+    if(!this.config_.animationLoop.started) {
+      this.config_.animationLoop.interval = this.config_.interval;
+      let direction = 'next';
+
+      if('scroll' === this.config_.type) {
+        this.config_.animationLoop.start( () => {
+          direction = nextScroll(direction);
+          return true; // It runs until cancelSlideShow_ is triggered
+        });
+      }
+      else {
+        nextSlide();
+        this.config_.animationLoop.start( () => {
+          return nextSlide(); // It runs until cancelSlideShow_ is triggered
+        });
+      }
+    }
+
+    // TODO: Pause animation when carousel is not in browser viewport or user changes tab
+  };
+
+  /**
+   * Cancel slideshow if running. Emmits a 'pause' event
+   * @private
+   */
+  MaterialExtCarousel.prototype.cancelSlideShow_ = function() {
+    if(this.config_.animationLoop.started) {
+      this.config_.animationLoop.stop();
+      this.emitSelectEvent_('pause', VK_ESC, this.element_.querySelector(`.${SLIDE}[aria-selected]`));
+    }
+  };
+
+  /**
+   * Animate scroll
+   * @param newPosition
+   * @param newDuration
+   * @param completedCallback
+   * @private
+   */
+  MaterialExtCarousel.prototype.animateScroll_ = function( newPosition, newDuration, completedCallback ) {
+
+    const start = this.element_.scrollLeft;
+    const distance = newPosition - start;
+
+    if(distance !== 0) {
+      const duration = Math.max(Math.min(Math.abs(distance), newDuration||400), 100); // duration is between 100 and newDuration||400ms||distance
+      let t = 0;
+      this.scrollAnimation_.stop();
+      this.scrollAnimation_.start( timeElapsed => {
+        t += timeElapsed;
+        if(t < duration) {
+          this.element_.scrollLeft = inOutQuintic(t, start, distance, duration);
+          return true;
+        }
+        else {
+          this.element_.scrollLeft = newPosition;
+          if(completedCallback) {
+            completedCallback();
+          }
+          return false;
+        }
+      });
+    }
+    else {
+      if(completedCallback) {
+        completedCallback();
+      }
+    }
+  };
+
+  /**
+   * Execute commend
+   * @param event
+   * @private
+   */
+  MaterialExtCarousel.prototype.command_ = function( event ) {
+    let x = 0;
+    let slide = null;
+    const a = event.detail.action.toLowerCase();
+
+    // Cancel slideshow if running
+    this.cancelSlideShow_();
+
+    switch (a) {
+      case 'first':
+        slide = this.element_.querySelector(`.${SLIDE}:first-child`);
+        break;
+
+      case 'last':
+        x = this.element_.scrollWidth - this.element_.clientWidth;
+        slide = this.element_.querySelector(`.${SLIDE}:last-child`);
+        break;
+
+      case 'scroll-prev':
+        x = Math.max(this.element_.scrollLeft - this.element_.clientWidth, 0);
+        break;
+
+      case 'scroll-next':
+        x = Math.min(this.element_.scrollLeft + this.element_.clientWidth, this.element_.scrollWidth - this.element_.clientWidth);
+        break;
+
+      case 'next':
+      case 'prev':
+        slide = this.element_.querySelector(`.${SLIDE}[aria-selected]`);
+        if(slide) {
+          slide = a === 'next' ? slide.nextElementSibling : slide.previousElementSibling;
+          this.setAriaSelected_(slide);
+          this.emitSelectEvent_(a, null,  slide);
+        }
+        return;
+
+      case 'play':
+        Object.assign(this.config_, event.detail);
+        this.startSlideShow_();
+        return;
+
+      case 'pause':
+        return;
+
+      default:
+        return;
+    }
+
+    this.animateScroll_(x, undefined, () => {
+      if ('scroll-next' === a || 'scroll-prev' === a) {
+        const slides = this.getSlidesInViewport_();
+        if (slides.length > 0) {
+          slide = 'scroll-next' === a ? slides[0] : slides[slides.length - 1];
+        }
+      }
+      this.setAriaSelected_(slide);
+      this.emitSelectEvent_(a, null, slide);
+    });
+  };
+
+  /**
+   * Handles custom command event, 'scroll-prev', 'scroll-next', 'first', 'last', next, prev, play, pause
+   * @param event. A custom event
+   * @private
+   */
+  MaterialExtCarousel.prototype.commandHandler_ = function( event ) {
+    event.preventDefault();
+    event.stopPropagation();
+    if(event.detail && event.detail.action) {
+      this.command_(event);
+    }
+  };
+
+  /**
+   * Handle keypress
+   * @param event
+   * @private
+   */
+  MaterialExtCarousel.prototype.keyDownHandler_ = function(event) {
+
+    if (event && event.target && event.target !== this.element_) {
+
+      let action = 'first';
+
+      if ( event.keyCode === VK_HOME    || event.keyCode === VK_END
+        || event.keyCode === VK_PAGE_UP || event.keyCode === VK_PAGE_DOWN) {
+
+        event.preventDefault();
+        if (event.keyCode === VK_END) {
+          action = 'last';
+        }
+        else if (event.keyCode === VK_PAGE_UP) {
+          action = 'scroll-prev';
+        }
+        else if (event.keyCode === VK_PAGE_DOWN) {
+          action = 'scroll-next';
+        }
+
+        const cmd = new CustomEvent('select', {
+          detail: {
+            action: action,
+          }
+        });
+        this.command_(cmd);
+      }
+      else if ( event.keyCode === VK_TAB
+        || event.keyCode === VK_ENTER      || event.keyCode === VK_SPACE
+        || event.keyCode === VK_ARROW_UP   || event.keyCode === VK_ARROW_LEFT
+        || event.keyCode === VK_ARROW_DOWN || event.keyCode === VK_ARROW_RIGHT) {
+
+        let slide = getSlide_(event.target);
+
+        if(!slide) {
+          return;
+        }
+
+        // Cancel slideshow if running
+        this.cancelSlideShow_();
+
+        switch (event.keyCode) {
+          case VK_ARROW_UP:
+          case VK_ARROW_LEFT:
+            action = 'prev';
+            slide = slide.previousElementSibling;
+            break;
+
+          case VK_ARROW_DOWN:
+          case VK_ARROW_RIGHT:
+            action = 'next';
+            slide = slide.nextElementSibling;
+            break;
+
+          case VK_TAB:
+            if (event.shiftKey) {
+              action = 'prev';
+              slide = slide.previousElementSibling;
+            }
+            else {
+              action = 'next';
+              slide = slide.nextElementSibling;
+            }
+            break;
+
+          case VK_SPACE:
+          case VK_ENTER:
+            action = 'select';
+            break;
+        }
+
+        if(slide) {
+          event.preventDefault();
+          setFocus_(slide);
+          this.emitSelectEvent_(action, event.keyCode, slide);
+        }
+      }
+    }
+  };
+
+  /**
+   * Handle dragging
+   * @param event
+   * @private
+   */
+  MaterialExtCarousel.prototype.dragHandler_ = function(event) {
+    event.preventDefault();
+
+    // Cancel slideshow if running
+    this.cancelSlideShow_();
+
+    let updating = false;
+    let rAFDragId = 0;
+
+    const startX = event.clientX || (event.touches !== undefined ? event.touches[0].clientX : 0);
+    let prevX = startX;
+    const targetElement = event.target;
+
+    const update = e => {
+      const currentX = (e.clientX || (e.touches !== undefined ? e.touches[0].clientX : 0));
+      const dx = prevX - currentX;
+
+      if(dx < 0) {
+        this.element_.scrollLeft = Math.max(this.element_.scrollLeft + dx, 0);
+      }
+      else if(dx > 0) {
+        this.element_.scrollLeft = Math.min(this.element_.scrollLeft + dx, this.element_.scrollWidth - this.element_.clientWidth);
+      }
+
+      prevX = currentX;
+      updating = false;
+    };
+
+    // drag handler
+    const drag = e => {
+      e.preventDefault();
+
+      if(!updating) {
+        rAFDragId = window.requestAnimationFrame( () => update(e));
+        updating = true;
+      }
+    };
+
+    // end drag handler
+    const endDrag = e => {
+      e.preventDefault();
+
+      this.element_.removeEventListener('mousemove', drag);
+      this.element_.removeEventListener('touchmove', drag);
+      window.removeEventListener('mouseup', endDrag);
+      window.removeEventListener('touchend', endDrag);
+
+      // cancel any existing drag rAF, see: http://www.html5rocks.com/en/tutorials/speed/animations/
+      window.cancelAnimationFrame(rAFDragId);
+
+      const slide = getSlide_(targetElement);
+      setFocus_(slide);
+      this.emitSelectEvent_('click', null,  slide);
+    };
+
+    this.element_.addEventListener('mousemove', drag);
+    this.element_.addEventListener('touchmove', drag);
+    window.addEventListener('mouseup', endDrag);
+    window.addEventListener('touchend',endDrag);
+  };
+
+  /**
+   * Handle click
+   * @param event
+   * @private
+   */
+  MaterialExtCarousel.prototype.clickHandler_ = function(event) {
+    // Click is handled by drag
+    event.preventDefault();
+  };
+
+  /**
+   * Handle focus
+   * @param event
+   * @private
+   */
+  MaterialExtCarousel.prototype.focusHandler_ = function(event) {
+    const slide = getSlide_(event.target);
+    if(slide) {
+      // The last focused/selected slide has 'aria-selected', even if focus is lost
+      this.setAriaSelected_(slide);
+      slide.classList.add(IS_FOCUSED);
+    }
+  };
+
+  /**
+   * Handle blur
+   * @param event
+   * @private
+   */
+  MaterialExtCarousel.prototype.blurHandler_ = function(event) {
+    const slide = getSlide_(event.target);
+    if(slide) {
+      slide.classList.remove(IS_FOCUSED);
+    }
+  };
+
+  /**
+   * Emits a custeom 'select' event
+   * @param command
+   * @param keyCode
+   * @param slide
+   * @private
+   */
+  MaterialExtCarousel.prototype.emitSelectEvent_ = function(command, keyCode, slide) {
+
+    if(slide) {
+      this.moveSlideIntoViewport_(slide);
+
+      const evt = new CustomEvent('select', {
+        bubbles: true,
+        cancelable: true,
+        detail: {
+          command: command,
+          keyCode: keyCode,
+          source: slide
+        }
+      });
+      this.element_.dispatchEvent(evt);
+    }
+  };
+
+  /**
+   * Get the first visible slide in component viewport
+   * @private
+   */
+  MaterialExtCarousel.prototype.getSlidesInViewport_ = function() {
+    const carouselRect = this.element_.getBoundingClientRect();
+
+    const slidesInViewport = [...this.element_.querySelectorAll(`.${SLIDE}`)].filter( slide => {
+      const slideRect = slide.getBoundingClientRect();
+      return slideRect.left >= carouselRect.left && slideRect.right <= carouselRect.right;
+    });
+    return slidesInViewport;
+  };
+
+  /**
+   * Move slide into component viewport - if needed
+   * @param slide
+   * @private
+   */
+  MaterialExtCarousel.prototype.moveSlideIntoViewport_ = function(slide) {
+    const carouselRect = this.element_.getBoundingClientRect();
+    const slideRect = slide.getBoundingClientRect();
+
+    if(slideRect.left < carouselRect.left) {
+      const x = this.element_.scrollLeft - (carouselRect.left - slideRect.left);
+      this.animateScroll_(x);
+    }
+    else if(slideRect.right > carouselRect.right) {
+      const x = this.element_.scrollLeft - (carouselRect.right - slideRect.right);
+      this.animateScroll_(x);
+    }
+  };
+
+
+  /**
+   * Removes 'aria-selected' from all slides in carousel
+   * @private
+   */
+  MaterialExtCarousel.prototype.setAriaSelected_ = function(slide) {
+    if(slide) {
+      [...this.element_.querySelectorAll(`.${SLIDE}[aria-selected]`)].forEach(
+        slide => slide.removeAttribute('aria-selected')
+      );
+      slide.setAttribute('aria-selected', '');
+    }
+  };
+
+  /**
+   * Removes event listeners
+   * @private
+   */
+  MaterialExtCarousel.prototype.removeListeners_ = function() {
+    this.element_.removeEventListener('focus', this.focusHandler_);
+    this.element_.removeEventListener('blur', this.blurHandler_);
+    this.element_.removeEventListener('keydown', this.keyDownHandler_);
+    this.element_.removeEventListener('mousedown', this.dragHandler_);
+    this.element_.removeEventListener('touchstart', this.dragHandler_);
+    this.element_.removeEventListener('click', this.clickHandler_, false);
+    this.element_.removeEventListener('command', this.commandHandler_);
+    this.element_.removeEventListener('mdl-componentdowngraded', this.mdlDowngrade_);
+  };
+
+
+  // Helpers
+  const getSlide_ = element => {
+    return element.closest(`.${SLIDE}`);
+  };
+
+  const setFocus_ = slide => {
+    if(slide) {
+      slide.focus();
+    }
+  };
+
+  const addRipple_ = slide => {
+    if(!slide.querySelector(`.${MDL_RIPPLE_CONTAINER}`)) {
+      const rippleContainer = document.createElement('span');
+      rippleContainer.classList.add(MDL_RIPPLE_CONTAINER);
+      rippleContainer.classList.add(MDL_RIPPLE_EFFECT);
+      const ripple = document.createElement('span');
+      ripple.classList.add(MDL_RIPPLE);
+      rippleContainer.appendChild(ripple);
+
+      const img = slide.querySelector('img');
+      if (img) {
+        // rippleContainer blocks image title
+        rippleContainer.title = img.title;
+      }
+      slide.appendChild(rippleContainer);
+      componentHandler.upgradeElement(rippleContainer, MDL_RIPPLE_COMPONENT);
+    }
+  };
+  // End helpers
+
+
+  // Public methods.
+
+  /**
+   * Cancel animation - if running.
+   *
+   * @public
+   */
+  MaterialExtCarousel.prototype.stopAnimation = function() {
+    this.config_.animationLoop.stop();
+  };
+  MaterialExtCarousel.prototype['stopAnimation'] = MaterialExtCarousel.prototype.stopAnimation;
+
+
+  /**
+   * Upgrade slides
+   * Use if more list elements are added later (dynamically)
+   *
+   * @public
+   */
+  MaterialExtCarousel.prototype.upgradeSlides = function() {
+
+    const hasRippleEffect = this.element_.classList.contains(MDL_RIPPLE_EFFECT);
+
+    [...this.element_.querySelectorAll(`.${SLIDE}`)].forEach( slide => {
+
+      slide.setAttribute('role', SLIDE_ROLE);
+
+      if(this.config_.interactive) {
+        if(!slide.getAttribute('tabindex')) {
+          slide.setAttribute('tabindex', '0');
+        }
+        if (hasRippleEffect) {
+          addRipple_(slide);
+        }
+      }
+      else {
+        slide.setAttribute('tabindex', '-1');
+      }
+    });
+  };
+  MaterialExtCarousel.prototype['upgradeSlides'] = MaterialExtCarousel.prototype.upgradeSlides;
+
+
+  /**
+   * Get config object
+   *
+   * @public
+   */
+  MaterialExtCarousel.prototype.getConfig = function() {
+    return this.config_;
+  };
+  MaterialExtCarousel.prototype['getConfig'] = MaterialExtCarousel.prototype.getConfig;
+
+  /**
+   * Initialize component
+   */
+  MaterialExtCarousel.prototype.init = function() {
+
+    if (this.element_) {
+      // Config
+      if(this.element_.hasAttribute('data-config')) {
+        this.config_ = jsonStringToObject(this.element_.getAttribute('data-config'), this.config_);
+      }
+
+      // Wai-Aria
+      this.element_.setAttribute('role', ROLE);
+
+      // Prefer tabindex -1
+      if(!Number.isInteger(this.element_.getAttribute('tabindex'))) {
+        this.element_.setAttribute('tabindex', -1);
+      }
+
+      // Remove listeners, just in case ...
+      this.removeListeners_();
+
+      if(this.config_.interactive) {
+
+        // Ripple
+        const hasRippleEffect = this.element_.classList.contains(MDL_RIPPLE_EFFECT);
+        if (hasRippleEffect) {
+          this.element_.classList.add(MDL_RIPPLE_EFFECT_IGNORE_EVENTS);
+        }
+
+        // Listen to focus/blur events
+        this.element_.addEventListener('focus', this.focusHandler_.bind(this), true);
+        this.element_.addEventListener('blur', this.blurHandler_.bind(this), true);
+
+        // Listen to keyboard events
+        this.element_.addEventListener('keydown', this.keyDownHandler_.bind(this), false);
+
+        // Listen to drag events
+        this.element_.addEventListener('mousedown', this.dragHandler_.bind(this), false);
+        this.element_.addEventListener('touchstart', this.dragHandler_.bind(this), false);
+
+        // Listen to click events
+        this.element_.addEventListener('click', this.clickHandler_.bind(this), false);
+      }
+
+      // Listen to custom 'command' event
+      this.element_.addEventListener('command', this.commandHandler_.bind(this), false);
+
+      // Listen to 'mdl-componentdowngraded' event
+      this.element_.addEventListener('mdl-componentdowngraded', this.mdlDowngrade_.bind(this));
+
+      // Slides collection
+      this.upgradeSlides();
+
+      // Set upgraded flag
+      this.element_.classList.add(IS_UPGRADED);
+
+      if(this.config_.autostart) {
+        // Start slideshow
+        this.startSlideShow_();
+      }
+    }
+  };
+
+  /*
+   * Downgrade component
+   * E.g remove listeners and clean up resources
+   */
+  MaterialExtCarousel.prototype.mdlDowngrade_ = function() {
+    'use strict';
+    //console.log('***** MaterialExtCarousel.mdlDowngrade_');
+
+    // Stop animation - if any
+    this.stopAnimation();
+
+    // Remove listeners
+    this.removeListeners_();
+  };
+
+  // The component registers itself. It can assume componentHandler is available
+  // in the global scope.
+  /* eslint no-undef: 0 */
+  componentHandler.register({
+    constructor: MaterialExtCarousel,
+    classAsString: 'MaterialExtCarousel',
+    cssClass: 'mdlext-js-carousel',
+    widget: true
+  });
+})();
diff --git a/node_modules/mdl-ext/src/carousel/readme.md b/node_modules/mdl-ext/src/carousel/readme.md
new file mode 100644
index 0000000..6485972
--- /dev/null
+++ b/node_modules/mdl-ext/src/carousel/readme.md
@@ -0,0 +1,271 @@
+# Carousel
+
+![Carousel](../../etc/carousel.png)
+
+A responsive image carousel.
+
+## Introduction
+The Material Design Lite Ext (MDLEXT) Carousel, commonly also referred to as “slide shows” or “sliders”, is a component 
+for cycling through a series of images. The carousel is defined and enclosed by a container element and 
+distributes images horizontally, with repect to the available container size. Images outside the container viewport slides
+into view, triggerd by a user action or by running an animation loop (rAF). 
+
+This component does not attempt in any way to resemble a three-dimensional image carousel that is used to show slides 
+from a projector. The component is perceived more as a slider, but the terms slider and carousel, are often used 
+interchangeably.
+
+### Features:
+* Navigate carousel using keyboard (arrow keys, tab, pgup, pgdown, home, end), mouse drag, touch events, or by sending custom events to the carousel (first, scroll-prev, prev, next, scroll-next, last, play, pause)
+* Select a particular image  using enter or space key, or by clicking an image 
+* Cycle images at a given interval - a slideshow
+* Set slideshow interval via a data attribute or as a part of the play custom event
+* Stop slideshow via custom event (pause) or by a user interaction, e.g clicking an image
+* User interactions via keyboard, mouse or touch events may be blocked, if configured 
+* Start slideshow at component initialization using a data attribute
+* The carousel emits custom events reflecting a user action. E.g. clicking an image will emit a 'select' event with a detail object holding a reference to the selected image.
+
+### Limitations:
+* The carousel should pause any running animation on window.bur or tab.blur - not implemented
+* The carousel should pause any running animation when the carousel is not in window viewport - not implemented
+* Only horizontal layout in first release
+
+
+### To include a MDLEXT **carousel** component:
+&nbsp;1. Code a block element, e.g. a `<div>` element, to hold dimensions of the carousel. 
+```html
+<div style="height: 200px; width: 100%;">
+</div>
+```
+
+&nbsp;2. Code a `<ul>` element with `class="mdlext-carousel mdlext-js-carousel"` to hold the carousel. 
+```html
+<div style="height: 200px; width: 100%;">
+  <ul class="mdlext-carousel mdlext-js-carousel">
+  <ul>
+</div>
+```
+
+&nbsp;3. Code a `<li>` element with `class="mdlext-carousel__slide"`  to hold an individual image (thumbnail). 
+```html
+<div style="height: 200px; width: 100%;">
+  <ul class="mdlext-carousel mdlext-js-carousel">
+    <li class="mdlext-carousel__slide">
+    <li>
+  <ul>
+</div>
+```
+
+&nbsp;4. Code a `<figure>` element to hold the image and the image title.  
+```html
+<div style="height: 200px; width: 100%;">
+  <ul class="mdlext-carousel mdlext-js-carousel">
+    <li class="mdlext-carousel__slide">
+      <figure>
+      </figure>
+    <li>
+  <ul>
+</div>
+```
+
+&nbsp;5. Inside the `<figure>` element add an `<img>` element with reference to the thumbnail image to be shown. Optionally add a `<figcaption>` element to hold the image title.    
+```html
+<div style="height: 200px; width: 100%;">
+  <ul class="mdlext-carousel mdlext-js-carousel">
+    <li class="mdlext-carousel__slide">
+      <figure>
+        <img src="_D802591.jpg" title="Whooper swans in flight"/>
+        <figcaption>_D802591.jpg</figcaption>
+      </figure>
+    <li>
+  <ul>
+</div>
+```
+
+&nbsp;6. Repeat steps 3..5 for each slide required.
+
+### Examples
+* See: [snippets/carousel.html](./snippets/carousel.html)
+* Or try out the [live demo](http://leifoolsen.github.io/mdl-ext/demo/carousel.html)
+
+## Interactions
+
+### Keyboard interaction
+The carousel interacts with the following keyboard keys.
+
+*   `Tab` - When focus is on a slide, pressing the `Tab` key moves focus in the following manner:
+      *   If there is a next slide, focus moves to the next slide.
+      *   If focus is on the last slide, focus moves to the first focusable element outside the carousel component.
+*   `Shift+Tab` - Generally the reverse of `Tab`.
+*   `Left arrow` - Moves focus to the previous slide. If the current slide is the first slide, focus stays on that slide.
+*   `Right arrow` - Moves focus to the next slide. If the current slide is the last slide, focus stays on that slide.
+*   `Up arrow` - behaves the same as left arrow.
+*   `Down arrow` - behaves the same as right arrow.
+*   `End` - When focus is on a slide, an `End` key press moves focus to the last slide.
+*   `Home` - When focus is on a slide, a `Home` key press moves focus to the first slide.
+*   `Enter/Space` - When focus is on a slide, pressing `Enter` or `Space` selects the focused slide.
+
+### Mouse / Touch interaction
+*   `Drag or Swipe left` - Move slides outside container viewport into view.
+*   `Drag or Swipe right` - Move slides outside container viewport into view
+
+
+## Component configuration
+The component can be configured using a `data-config` attribute. The attribute value is a JSON string with the following properties.
+
+| Property        |    |    |
+|-----------------|----|----|
+| `interactive`   | if `true`, the user can use keyboard or mouse to navigate the slides | default: `true` |
+| `autostart`     | if `true`, the slideshow starts immediately after component initialization | default: `false` |
+| `type`          | animation type, `'slide'`, advances one slide,  `'scroll'`, moves next sequence of slides into view | default `'slide'` |
+| `interval`      | animation interval, in milliseconds | default `1000` |
+
+
+The `data-config` attribute must be a valid JSON string. You can use single or double quotes for the JSON properties. 
+
+Example 1, single quotes in JSON config string:
+```html
+<ul class="mdlext-carousel mdlext-js-carousel mdl-js-ripple-effect mdl-js-ripple-effect--ignore-events" 
+  data-config="{ 'interactive': true, 'autostart': false, 'type': 'slide', 'interval': 2000 }">
+  ......
+</ul>
+```
+
+Example 2, double quotes in JSON config string:
+```html
+<ul class="mdlext-carousel mdlext-js-carousel" 
+  data-config='{ "interactive": false, "autostart": true, "type": "scroll", "interval": 5000 }'>
+  ......
+</ul>
+```
+
+## Events
+Interaction with the component programmatically is performed by sending events to the component, and receive responses 
+from the component.  
+
+### Events the component listenes to
+A client can send a `command` custom event to the carousel. The command event holds an action detail object defining 
+the action to perform.
+
+```javascript
+new CustomEvent('command', { detail: { action : 'first' } });
+new CustomEvent('command', { detail: { action : 'scroll-prev' } });
+new CustomEvent('command', { detail: { action : 'prev' } });
+new CustomEvent('command', { detail: { action : 'next' } });
+new CustomEvent('command', { detail: { action : 'scroll-next' } });
+new CustomEvent('command', { detail: { action : 'last' } });
+new CustomEvent('command', { detail: 
+  { 
+    action : 'play', 
+    interval: 3000   // Interval is optional, overrides value set by 'data-config'
+  } 
+}); 
+new CustomEvent('command', { detail: { action : 'pause' } });
+
+// Trigger the event
+myCarousel.dispatchEvent(ev);
+```
+
+Refer to [snippets/lightbox.html](./snippets/carousel.html) for usage.
+
+### Events emitted
+When a user interacts with the component, or the component receives a `command` custom event, the component responds
+with a `select` custom event reflecting the action performed and a detail object holding the selected slide element.
+
+The `select` detail object has the following format:
+
+```javascript
+detail: {
+  command, // The command executed (`first`, `scroll-prev`, `prev`, `next`, `scroll-next`, `last`) 
+  keyCode, // Key pressed, if any 
+  source   // The element that caused the event
+}
+```
+
+Set up a `select` listener.
+```javascript
+document.querySelector('#my-carousel').addEventListener('select', function(e) {
+  var selectedElement = e.detail.source;
+  console.log('Selected element', selectedElement);
+  var selectImage = selectedElement.querySelector('img');
+});
+
+```
+Refer to [snippets/lightbox.html](./snippets/carousel.html) for usage.
+
+
+## Public methods
+
+### `stopAnimation()`
+
+Stops animation - if any.
+
+### `upgradeSlides()`
+Upgrade slides. If you add slides to the carousel after the page has loaded, you must call `upgradeSlides` to 
+notify the component about the newly inserted slides.
+
+```javascript
+myCarousel = document.querySelector('#my-carousel');
+myCarousel.MaterialExtCarousel.upgradeSlides();
+```
+
+### `getConfig()`
+Returns the `config` object.
+
+
+## Configuration options
+The MDLEXT CSS classes apply various predefined visual and behavioral enhancements to the carousel.
+The table below lists the available classes and their effects.
+
+| MDLEXT class | Effect | Remarks |
+|--------------|--------|---------|
+| `mdlext-carousel` | Defines a container as an MDLEXT carousel component | Required on `<ul>` element |
+| `mdlext-js-carousel` | Assigns basic MDL behavior to carousel | Required on `<ul>` element |
+| `mdlext-carousel__slide` | Defines a carousel slide | Required on `<li>` element |
+
+Attributes.
+
+| Attribute | Effect | Remarks |
+|-----------|--------|---------|
+| `data-config` | A JSON object defining startup configurations |  |
+| `aria-selected` | The selected `mdlext-carousel__slide` element | Only one element can be selected at the same time |
+| `list` | The component add the role `list` to self |  |
+| `listitem` | The component add the role `listitem` to `mdlext-carousel__slide` items |  |
+
+
+## Note for single page applications
+If you use Material Design Lite in a dynamic page, e.g. a single page application, any running animations must be 
+stopped before a page frament containing a carousel component is removed from the DOM. Call 
+`componentHandler.downgradeElements` to stop any running animation and clean up component resources. 
+In a static web application there should be no need to call `componentHandler.downgradeElements`.
+
+The following code snippet demonstrates how to properly clean up components before removing them from DOM.
+
+```javascript
+// Call 'componentHandler.downgradeElements' to clean up
+const content = document.querySelector('#content');
+const components = content.querySelectorAll('.is-upgraded');
+componentHandler.downgradeElements([...components]);
+
+// Remove elements from DOM.
+// See: http://jsperf.com/empty-an-element/16
+const removeChildElements = (element, forceReflow = true) => {
+  while (element.lastChild) {
+    element.removeChild(element.lastChild);
+  }
+  if(forceReflow) {
+    // See: http://jsperf.com/force-reflow
+    const d = element.style.display;
+    element.style.display = 'none';
+    element.style.display = d;
+  }
+}
+
+removeChildElements(content); 
+```
+
+## How to use the component programmatically
+The [tests](../../test/carousel/carousel.spec.js) and the [snippets/lightbox.html](./snippets/carousel.html) 
+code provides examples on how to use the component programmatically.
+
+## Reference
+[WCAG Carousel Concepts](https://www.w3.org/WAI/tutorials/carousels/)
diff --git a/node_modules/mdl-ext/src/carousel/snippets/carousel.html b/node_modules/mdl-ext/src/carousel/snippets/carousel.html
new file mode 100644
index 0000000..ac51213
--- /dev/null
+++ b/node_modules/mdl-ext/src/carousel/snippets/carousel.html
@@ -0,0 +1,612 @@
+<p><strong>Note:</strong> Does not work as expected in IE11</p>
+
+<style>
+  .carousel-demo {
+    box-sizing: border-box;
+    display: block;
+    padding: 4px;
+    border: 1px solid #dddddd;
+    border-radius: 4px;
+    box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 3px 1px -2px rgba(0, 0, 0, 0.2), 0 1px 5px 0 rgba(0, 0, 0, 0.12);
+  }
+
+  .carousel-demo * {
+    box-sizing: border-box;
+  }
+
+  #carousel-imgviewer {
+    display: -webkit-box;
+    display: -ms-flexbox;
+    display: flex;
+    -webkit-box-pack: center;
+    -ms-flex-pack: center;
+    justify-content: center;
+  }
+
+  #carousel-imgviewer figure {
+    display: -webkit-box;
+    display: -ms-flexbox;
+    display: flex;
+    -webkit-box-orient: vertical;
+    -webkit-box-direction: normal;
+    -ms-flex-direction: column;
+    flex-direction: column;
+    -webkit-box-pack: center;
+    -ms-flex-pack: center;
+    justify-content: center;
+
+    position: relative;
+    height: 100%;
+    padding: 0;
+    margin: 0;
+  }
+
+  #carousel-imgviewer figure img {
+    width: auto;
+    max-width: 100%;
+    max-height: 100%;
+    border: 0;
+    outline: 0;
+
+    -webkit-animation: fade-in-element 0.25s ease-out;
+    -moz-animation: fade-in-element 0.25s ease-out;
+    -o-animation: fade-in-element 025s ease-out;
+    animation: fade-in-element 0.25s ease-out;
+  }
+
+  #carousel-footer {
+    display: -webkit-box;
+    display: -ms-flexbox;
+    display: flex;
+    -webkit-box-pack: justify;
+    -ms-flex-pack: justify;
+    justify-content: space-between;
+    -webkit-box-align: center;
+    -ms-flex-align: center;
+    align-items: center;
+  }
+
+  #carousel-footer .mdl-card__supporting-text {
+    -webkit-box-flex: 1;
+    -ms-flex: 1;
+    flex: 1;
+    overflow: hidden;
+    white-space: nowrap;
+    text-overflow: ellipsis;
+    padding: 0;
+    width: 100%;
+  }
+
+  #carousel-footer nav {
+    display: -webkit-box;
+    display: -ms-flexbox;
+    display: flex;
+  }
+
+  .carousel-button {
+  }
+  .carousel-button__icon {
+    font-size: 24px;
+  }
+
+  #carousel-container {
+  }
+
+  @media (max-width: 479px) {
+    #carousel-imgviewer {
+      height: 260px;
+    }
+    .carousel-button {
+      width: 28px;
+      min-width: 28px;
+      height: 28px;
+    }
+    .carousel-button__icon {
+      font-size: 20px;
+    }
+    #carousel-container {
+      height: 60px;
+      margin-top: 4px;
+    }
+  }
+
+  @media (min-width: 480px) and (max-width: 839px) {
+    #carousel-imgviewer {
+      height: 360px;
+    }
+    #carousel-container {
+      height: 90px;
+    }
+  }
+
+  @media (min-width: 840px) {
+    #carousel-imgviewer {
+      height: 500px;
+    }
+    #carousel-container {
+      height: 110px;
+    }
+  }
+
+  @-webkit-keyframes fade-in-element {
+    0%   { opacity: 0; }
+    100% { opacity: 1; }
+  }
+  @-moz-keyframes fade-in-element {
+    0%   { opacity: 0; }
+    100% { opacity: 1; }
+  }
+  @-o-keyframes fade-in-element {
+    0%   { opacity: 0; }
+    100% { opacity: 1; }
+  }
+  @keyframes fade-in-element {
+    0%   { opacity: 0; }
+    100% { opacity: 1; }
+  }
+
+</style>
+
+<artichle class="carousel-demo" style="height: 64px; margin-bottom: 16px; padding-top: 1px;">
+  <ul class="mdlext-carousel mdlext-js-carousel"
+      data-config="{ 'interactive': false, 'autostart': true, 'type': 'scroll', 'interval': 5000 }">
+
+    <li class="mdlext-carousel__slide">
+      <figure>
+        <img src="./images/_D802141.jpg" title="Northern goshawk with prey"/>
+      </figure>
+    </li>
+    <li class="mdlext-carousel__slide">
+      <figure>
+        <img src="./images/_D802143.jpg" title="Northern goshawk with prey"/>
+      </figure>
+    </li>
+    <li class="mdlext-carousel__slide">
+      <figure>
+        <img src="./images/_D802591.jpg" title="Whooper swans in flight"/>
+      </figure>
+    </li>
+    <li class="mdlext-carousel__slide">
+      <figure>
+        <img src="./images/_D804370-3.jpg" title="European green woodpecker"/>
+      </figure>
+    </li>
+    <li class="mdlext-carousel__slide">
+      <figure>
+        <img src="./images/_D808689.jpg" title="The bridge"/>
+      </figure>
+    </li>
+    <li class="mdlext-carousel__slide">
+      <figure>
+        <img src="./images/_D802181.jpg" title="Landscape in blue pastel"/>
+      </figure>
+    </li>
+    <li class="mdlext-carousel__slide">
+     <figure>
+        <img src="./images/_D800912.jpg" title="Hiking the mountains of Dovre"/>
+      </figure>
+    </li>
+    <li class="mdlext-carousel__slide">
+      <figure>
+        <img src="./images/_D809453-_D809457-4.jpg" title="The Polar Express. End of Line. Ny Aalesund, Spitsbergen" />
+      </figure>
+    </li>
+    <li class="mdlext-carousel__slide">
+      <figure>
+        <img src="./images/_DSC8214.jpg" title="Still got the blues"/>
+      </figure>
+    </li>
+    <li class="mdlext-carousel__slide">
+      <figure>
+        <img src="./images/_D800017.jpg" title="Flowers"/>
+      </figure>
+    </li>
+    <li class="mdlext-carousel__slide">
+      <figure>
+        <img src="./images/_D800023.jpg" title="Red-breasted merganser"/>
+      </figure>
+    </li>
+    <li class="mdlext-carousel__slide">
+      <figure>
+        <img src="./images/_D800851.jpg" title="Musk oxes, Dovre, Norway"/>
+      </figure>
+    </li>
+    <li class="mdlext-carousel__slide">
+      <figure>
+        <img src="./images/_D800166.jpg" title="Arctic Fox, Svalbard, Norway" />
+      </figure>
+    </li>
+    <li class="mdlext-carousel__slide">
+      <figure>
+        <img src="./images/_D800951.jpg" title="Fly fishing the arctic waters, Svalbard, Norway"/>
+      </figure>
+    </li>
+    <li class="mdlext-carousel__slide">
+      <figure>
+        <img src="./images/_D801188.jpg" title="Lady of the snows (Pulsatilla vernalis), Dovre, Norway"/>
+      </figure>
+    </li>
+    <li class="mdlext-carousel__slide">
+      <figure>
+        <img src="./images/_D801205-2.jpg" title="PULSE, Kilden Consert Hall, Kristiansand"/>
+      </figure>
+    </li>
+    <li class="mdlext-carousel__slide">
+      <figure>
+        <img src="./images/_D801274.jpg" title="PULSE, Kilden Consert Hall, Kristiansand"/>
+      </figure>
+    </li>
+    <li class="mdlext-carousel__slide">
+      <figure>
+        <img src="./images/_D801392.jpg" title="Peregrine falcon, Norway"/>
+      </figure>
+    </li>
+    <li class="mdlext-carousel__slide">
+      <figure>
+        <img src="./images/_D801436.jpg" title="Peregrine falcon, Norway"/>
+      </figure>
+    </li>
+    <li class="mdlext-carousel__slide">
+      <figure>
+        <img src="./images/_D801952-4.jpg" title="Mr. Per E Knudsen"/>
+      </figure>
+    </li>
+    <li class="mdlext-carousel__slide">
+      <figure>
+        <img src="./images/_D807603.jpg" title="Black Woodpecker"/>
+      </figure>
+    </li>
+    <li class="mdlext-carousel__slide">
+      <figure>
+        <img src="./images/_D807689.jpg" title="Goshina"/>
+      </figure>
+    </li>
+    <li class="mdlext-carousel__slide">
+      <figure>
+        <img src="./images/_D807558.jpg" title="Goshina"/>
+      </figure>
+    </li>
+    <li class="mdlext-carousel__slide">
+      <figure>
+        <img src="./images/_D800464.jpg" title="Svalbard Rock ptarmigan"/>
+      </figure>
+    </li>
+    <li class="mdlext-carousel__slide">
+      <figure>
+        <img src="./images/_DSC7535.jpg" title="Nice, France"/>
+      </figure>
+    </li>
+    <li class="mdlext-carousel__slide">
+      <figure>
+        <img src="./images/_D802478.jpg" title="Cheetah, Bloemfontain, South Africa"/>
+      </figure>
+    </li>
+    <li class="mdlext-carousel__slide">
+      <figure>
+        <img src="./images/_D800698.jpg" title="Red Squirrel"/>
+      </figure>
+    </li>
+    <li class="mdlext-carousel__slide">
+      <figure>
+        <img src="./images/_D803118.jpg" title="Milky Way, Bloemfontain, South Africa"/>
+      </figure>
+    </li>
+    <li class="mdlext-carousel__slide">
+      <figure>
+        <img src="./images/_D803521.jpg" title="Winter Light, Senja, Norway"/>
+      </figure>
+    </li>
+    <li class="mdlext-carousel__slide">
+      <figure>
+        <img src="./images/_D803465-3.jpg" title="Selfie with Aurora B :)"/>
+      </figure>
+    </li>
+    <li class="mdlext-carousel__slide">
+      <figure>
+        <img src="./images/_D806374.jpg" title="Lista Lighthouse, Norway"/>
+      </figure>
+    </li>
+    <li class="mdlext-carousel__slide">
+      <figure>
+        <img src="./images/_D805345-12.jpg" title="Osprey"/>
+      </figure>
+    </li>
+  </ul>
+</artichle>
+
+
+
+
+<artichle class="carousel-demo">
+
+  <section id="carousel-imgviewer">
+    <figure>
+      <img src="./images/_D802143-2.jpg" alt="" title=""/>
+    </figure>
+  </section>
+
+  <footer id="carousel-footer">
+    <div id="carousel-viewer-title" class="mdl-card__supporting-text">Northern goshawk with prey</div>
+    <nav>
+      <button id="carousel-btn-first" class="mdl-button mdl-button--icon mdl-js-button carousel-button" title="Scroll First">
+        <i class="material-icons carousel-button__icon">first_page</i>
+      </button>
+      <button id="carousel-btn-scroll-prev" class="mdl-button mdl-button--icon mdl-js-button carousel-button" title="Scroll Previous">
+        <i class="material-icons carousel-button__icon">fast_rewind</i>
+      </button>
+      <button id="carousel-btn-prev" class="mdl-button mdl-button--icon mdl-js-button carousel-button" title="Previous">
+        <i class="material-icons carousel-button__icon">navigate_before</i>
+      </button>
+      <button id="carousel-btn-play-pause" class="mdl-button mdl-button--icon mdl-js-button carousel-button" title="Play">
+        <i class="material-icons carousel-button__icon">play_circle_outline</i>
+      </button>
+      <button id="carousel-btn-next" class="mdl-button mdl-button--icon mdl-js-button carousel-button" title="Next">
+        <i class="material-icons carousel-button__icon">navigate_next</i>
+      </button>
+      <button id="carousel-btn-scroll-next" class="mdl-button mdl-button--icon mdl-js-button carousel-button" title="Scroll Next">
+        <i class="material-icons carousel-button__icon">fast_forward</i>
+      </button>
+      <button id="carousel-btn-last" class="mdl-button mdl-button--icon mdl-js-button carousel-button" title="Scroll Last">
+        <i class="material-icons carousel-button__icon">last_page</i>
+      </button>
+    </nav>
+  </footer>
+
+  <section id="carousel-container">
+    <ul id="mdlext-carousel-demo2" class="mdlext-carousel mdlext-js-carousel mdl-js-ripple-effect mdl-js-ripple-effect--ignore-events">
+      <li class="mdlext-carousel__slide" aria-selected >
+        <a href="./images/_D802143-2.jpg">
+          <figure>
+            <img src="./images/_D802143.jpg" title="Northern goshawk with prey"/>
+            <figcaption>_D802143.jpg</figcaption>
+          </figure>
+        </a>
+      </li>
+      <li class="mdlext-carousel__slide">
+        <a href="./images/_D802591-2.jpg">
+          <figure>
+            <img src="./images/_D802591.jpg" title="Whooper swans in flight"/>
+            <figcaption>_D802591.jpg</figcaption>
+          </figure>
+        </a>
+      </li>
+      <li class="mdlext-carousel__slide">
+        <figure>
+          <img src="./images/_D802181.jpg" title="Landscape in blue pastel"/>
+          <figcaption>_D802181.jpg</figcaption>
+        </figure>
+      </li>
+      <li class="mdlext-carousel__slide">
+        <a href="./images/_D809453-_D809457-3.jpg">
+          <figure>
+            <img src="./images/_D809453-_D809457-4.jpg" title="The Polar Express. End of Line. Ny Aalesund, Spitsbergen" />
+            <figcaption>_D809453</figcaption>
+          </figure>
+        </a>
+      </li>
+      <li class="mdlext-carousel__slide">
+        <a href="./images/_DSC8214-2.jpg">
+          <figure>
+            <img src="./images/_DSC8214.jpg" title="Still got the blues"/>
+            <figcaption>_DSC8214.jpg</figcaption>
+          </figure>
+        </a>
+      </li>
+      <li class="mdlext-carousel__slide">
+        <a href="./images/_D800166-2.jpg">
+          <figure>
+            <img src="./images/_D800166.jpg" title="Arctic Fox, Svalbard, Norway" />
+            <figcaption>_D800166.jpg</figcaption>
+          </figure>
+        </a>
+      </li>
+      <li class="mdlext-carousel__slide">
+        <a href="./images/_D801392-2.jpg">
+          <figure>
+            <img src="./images/_D801392.jpg" title="Peregrine falcon, Norway"/>
+            <figcaption>_D801392.jpg</figcaption>
+          </figure>
+        </a>
+      </li>
+      <li class="mdlext-carousel__slide">
+        <a href="./images/_D801436-2.jpg">
+          <figure>
+            <img src="./images/_D801436.jpg" title="Peregrine falcon, Norway"/>
+            <figcaption>_D801436.jpg</figcaption>
+          </figure>
+        </a>
+      </li>
+      <li class="mdlext-carousel__slide">
+        <figure>
+          <img src="./images/_D807558.jpg" title="Goshina"/>
+        </figure>
+      </li>
+      <li class="mdlext-carousel__slide">
+        <a href="./images/_D800464.jpg">
+          <figure>
+            <img src="./images/_D800464.jpg" title="Svalbard Rock ptarmigan"/>
+            <figcaption>_D800464.jpg</figcaption>
+          </figure>
+        </a>
+      </li>
+      <li class="mdlext-carousel__slide">
+        <a href="./images/_DSC7535-2.jpg">
+          <figure>
+            <img src="./images/_DSC7535.jpg" title="Nice, France"/>
+            <figcaption>_DSC7535.jpg</figcaption>
+          </figure>
+        </a>
+      </li>
+      <li class="mdlext-carousel__slide">
+        <figure>
+          <img src="./images/_D802478.jpg" title="Cheetah, Bloemfontain, South Africa"/>
+          <figcaption>_D802478.jpg</figcaption>
+        </figure>
+      </li>
+      <li class="mdlext-carousel__slide">
+        <figure>
+          <img src="./images/_D800698.jpg" title="Red Squirrel"/>
+          <figcaption>_D800698.jpg</figcaption>
+        </figure>
+      </li>
+      <li class="mdlext-carousel__slide">
+        <figure>
+          <img src="./images/_D803118.jpg" title="Milky Way, Bloemfontain, South Africa"/>
+          <figcaption>_D803118.jpg</figcaption>
+        </figure>
+      </li>
+      <li class="mdlext-carousel__slide">
+        <figure>
+          <img src="./images/_D803521.jpg" title="Winter Light, Senja, Norway"/>
+          <figcaption>_D803521.jpg</figcaption>
+        </figure>
+      </li>
+      <li class="mdlext-carousel__slide">
+        <figure>
+          <img src="./images/_D803465-3.jpg" title="Selfie with Aurora B :)"/>
+          <figcaption>_D803465.jpg</figcaption>
+        </figure>
+      </li>
+      <li class="mdlext-carousel__slide">
+        <figure>
+          <img src="./images/_D806374.jpg" title="Lista Lighthouse, Norway"/>
+          <figcaption>_D806374.jpg</figcaption>
+        </figure>
+      </li>
+      <li class="mdlext-carousel__slide">
+        <figure>
+          <img src="./images/_D801087.jpg" title="Brokke, Norway"/>
+          <figcaption>_D801087.jpg</figcaption>
+        </figure>
+      </li>
+      <li class="mdlext-carousel__slide">
+        <figure>
+          <img src="./images/_D803221.jpg" title="Mnt. Seglan, Senja, Norway"/>
+          <figcaption>_D803221.jpg</figcaption>
+        </figure>
+      </li>
+      <li class="mdlext-carousel__slide">
+        <figure>
+          <img src="./images/_D803759.jpg" title="Fruit bat, Mauritius"/>
+          <figcaption>_D803759.jpg</figcaption>
+        </figure>
+      </li>
+      <li class="mdlext-carousel__slide">
+        <figure>
+          <img src="./images/_D809758-2.jpg" title="Polar bear, Svalbard, Norway"/>
+          <figcaption>_D809758.jpg</figcaption>
+        </figure>
+      </li>
+      <li class="mdlext-carousel__slide">
+        <figure>
+          <img src="./images/_D805345-12.jpg" title="Osprey"/>
+          <figcaption>_D805345.jpg</figcaption>
+        </figure>
+      </li>
+    </ul>
+  </section>
+</artichle>
+
+
+<div style="margin-top: 8px">
+  <button id="btn-add-image" class="mdl-button mdl-js-button mdl-js-ripple-effect mdl-button--raised mdl-button--colored">
+    Add image to carousel
+  </button>
+  <p class="mdl-typography--caption" style="margin-top: 8px">
+    Click the button to add a new image to the carousel. Move to the inserted
+    image and click it. It should have ripple effect if upgraded correctly.
+  </p>
+</div>
+
+<p class="mdl-typography--caption" style="margin-top: 32px;">
+  All images appearing in this page are the exclusive property of Leif Olsen and are protected under the United States
+  and International Copyright laws. The images may not be reproduced or manipulated without the written permission of
+  Leif Olsen. Use of any image as the basis for another photographic concept or illustration (digital, artist rendering
+  or alike) is a violation of the United States and International Copyright laws. All images are copyrighted &copy; Leif Olsen, 2016.
+</p>
+
+
+<script>
+  (function() {
+    'use strict';
+
+    window.addEventListener('load', function() {
+
+      document.querySelector('#carousel-btn-first').addEventListener('click', function (e) {
+        var ev = new CustomEvent('command', {detail: {action: 'first'}});
+        document.querySelector('#mdlext-carousel-demo2').dispatchEvent(ev);
+      });
+
+      document.querySelector('#carousel-btn-scroll-prev').addEventListener('click', function (e) {
+        var ev = new CustomEvent('command', {detail: {action: 'scroll-prev'}});
+        document.querySelector('#mdlext-carousel-demo2').dispatchEvent(ev);
+      });
+
+      document.querySelector('#carousel-btn-prev').addEventListener('click', function (e) {
+        var ev = new CustomEvent('command', {detail: {action: 'prev'}});
+        document.querySelector('#mdlext-carousel-demo2').dispatchEvent(ev);
+      });
+
+      document.querySelector('#carousel-btn-next').addEventListener('click', function (e) {
+        var ev = new CustomEvent('command', {detail: {action: 'next'}});
+        document.querySelector('#mdlext-carousel-demo2').dispatchEvent(ev);
+      });
+
+      document.querySelector('#carousel-btn-scroll-next').addEventListener('click', function (e) {
+        var ev = new CustomEvent('command', {detail: {action: 'scroll-next'}});
+        document.querySelector('#mdlext-carousel-demo2').dispatchEvent(ev);
+      });
+
+      document.querySelector('#carousel-btn-last').addEventListener('click', function (e) {
+        var ev = new CustomEvent('command', {detail: {action: 'last'}});
+        document.querySelector('#mdlext-carousel-demo2').dispatchEvent(ev);
+      });
+
+      document.querySelector('#carousel-btn-play-pause').addEventListener('click', function (e) {
+        // Toggle play icon
+        var i = this.querySelector('i');
+        var action = i.innerText === 'play_circle_outline' ? 'play' : 'pause';
+        i.textContent = action === 'play' ? 'pause_circle_outline' : 'play_circle_outline';
+
+        var ev = new CustomEvent('command', {detail: {action: action, interval: 3000}});
+        document.querySelector('#mdlext-carousel-demo2').dispatchEvent(ev);
+      });
+
+      document.querySelector('#mdlext-carousel-demo2').addEventListener('select', function (e) {
+
+        if ('pause' === e.detail.command) {
+          // Set play icon
+          var i = document.querySelector('#carousel-btn-play-pause i');
+          i.textContent = 'play_circle_outline';
+        }
+        else {
+          var oldImage = document.querySelector('#carousel-imgviewer img');
+          var selectImage = e.detail.source.querySelector('img');
+          var selectImageSrc = selectImage.src;
+          if (e.detail.source.querySelector('a')) {
+            selectImageSrc = e.detail.source.querySelector('a').href;
+          }
+
+          if (selectImageSrc !== oldImage.src) {
+            var newImage = oldImage.cloneNode(true);
+            newImage.src = selectImageSrc;
+            oldImage.parentNode.replaceChild(newImage, oldImage);
+
+            var title = document.querySelector('#carousel-viewer-title');
+            title.textContent = selectImage.title;
+          }
+        }
+      });
+
+      document.querySelector('#btn-add-image').addEventListener('click', function (e) {
+        var slide_fragment = '<li class="mdlext-carousel__slide"><figure><img src="./images/_D809914-2.jpg" alt="Humpback whale" title="Humpback whale"/></figure></li>';
+        var carousel = document.querySelector('#mdlext-carousel-demo2');
+        carousel.insertAdjacentHTML('beforeend', slide_fragment);
+        carousel.MaterialExtCarousel.upgradeSlides();
+      });
+
+    });
+
+  }());
+
+</script>
diff --git a/node_modules/mdl-ext/src/collapsible/_collapsible.scss b/node_modules/mdl-ext/src/collapsible/_collapsible.scss
new file mode 100644
index 0000000..745676d
--- /dev/null
+++ b/node_modules/mdl-ext/src/collapsible/_collapsible.scss
@@ -0,0 +1,36 @@
+@charset "UTF-8";
+
+/**
+ * @license
+ * Copyright 2016-2017 Leif Olsen. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * This code is built with Google Material Design Lite,
+ * which is Licensed under the Apache License, Version 2.0
+ */
+
+.mdlext-collapsible {
+  box-sizing: border-box;
+  cursor: pointer;
+}
+
+.mdlext-collapsible-group,
+.mdlext-collapsible-region {
+  box-sizing: border-box;
+
+  &[hidden] {
+    @include mdlext-visually-hidden;
+    pointer-events: none;
+  }
+}
diff --git a/node_modules/mdl-ext/src/collapsible/collapsible.js b/node_modules/mdl-ext/src/collapsible/collapsible.js
new file mode 100644
index 0000000..862fffb
--- /dev/null
+++ b/node_modules/mdl-ext/src/collapsible/collapsible.js
@@ -0,0 +1,437 @@
+/**
+ * @license
+ * Copyright 2016-2017 Leif Olsen. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * This code is built with Google Material Design Lite,
+ * which is Licensed under the Apache License, Version 2.0
+ */
+
+
+/**
+ * A collapsible is a component to mark expandable and collapsible regions.
+ * The component use the aria-expanded state to indicate whether regions of
+ * the content are collapsible, and to expose whether a region is currently
+ * expanded or collapsed.
+ * @see https://www.w3.org/WAI/GL/wiki/Using_the_WAI-ARIA_aria-expanded_state_to_mark_expandable_and_collapsible_regions
+ */
+
+import {
+  IS_UPGRADED,
+  VK_SPACE,
+  VK_ENTER,
+} from '../utils/constants';
+
+import { randomString } from '../utils/string-utils';
+import { getParentElements, isFocusable } from '../utils/dom-utils';
+
+const JS_COLLAPSIBLE = 'mdlext-js-collapsible';
+const COLLAPSIBLE_CONTROL_CLASS = 'mdlext-collapsible';
+const COLLAPSIBLE_GROUP_CLASS = 'mdlext-collapsible-group';
+const COLLAPSIBLE_REGION_CLASS = 'mdlext-collapsible-region';
+
+/**
+ * The collapsible component
+ */
+
+class Collapsible {
+  element_ = null;
+  controlElement_ = null;
+
+  /**
+   * @constructor
+   * @param {HTMLElement} element The element that this component is connected to.
+   */
+  constructor(element) {
+    this.element_ = element;
+    this.init();
+  }
+
+  keyDownHandler = event => {
+    if (event.keyCode === VK_ENTER || event.keyCode === VK_SPACE) {
+      event.preventDefault();
+
+      // Trigger click
+      (event.target || this.controlElement).dispatchEvent(
+        new MouseEvent('click', {
+          bubbles: true,
+          cancelable: true,
+          view: window
+        })
+      );
+    }
+  };
+
+  clickHandler = event => {
+    if(!this.isDisabled) {
+      if(event.target !== this.controlElement) {
+        // Do not toggle if a focusable element inside the control element triggered the event
+        const p = getParentElements(event.target, this.controlElement);
+        p.push(event.target);
+        if(p.find( el => isFocusable(el))) {
+          return;
+        }
+      }
+      this.toggle();
+    }
+  };
+
+  get element() {
+    return this.element_;
+  }
+
+  get controlElement() {
+    return this.controlElement_;
+  }
+
+  get isDisabled() {
+    return (this.controlElement.hasAttribute('disabled') &&
+      this.controlElement.getAttribute('disabled').toLowerCase() !== 'false') ||
+      (this.controlElement.hasAttribute('aria-disabled') &&
+      this.controlElement.getAttribute('aria-disabled').toLowerCase() !== 'false');
+  }
+
+  get isExpanded() {
+    return this.controlElement.hasAttribute('aria-expanded') &&
+      this.controlElement.getAttribute('aria-expanded').toLowerCase() === 'true';
+  }
+
+  get regionIds() {
+    return this.controlElement.hasAttribute('aria-controls')
+      ? this.controlElement.getAttribute('aria-controls').split(' ')
+      : [];
+  }
+
+  get regionElements() {
+    return this.regionIds
+      .map(id => document.querySelector(`#${id}`))
+      .filter( el => el != null);
+  }
+
+  collapse() {
+    if(!this.isDisabled && this.isExpanded) {
+      if(this.dispatchToggleEvent('collapse')) {
+        this.controlElement.setAttribute('aria-expanded', 'false');
+        const regions = this.regionElements.slice(0);
+        for (let i = regions.length - 1; i >= 0; --i) {
+          regions[i].setAttribute('hidden', '');
+        }
+      }
+    }
+  }
+
+  expand() {
+    if(!this.isDisabled && !this.isExpanded) {
+      if(this.dispatchToggleEvent('expand')) {
+        this.controlElement.setAttribute('aria-expanded', 'true');
+        this.regionElements.forEach(region => region.removeAttribute('hidden'));
+      }
+    }
+  }
+
+  toggle() {
+    if (this.isExpanded) {
+      this.collapse();
+    }
+    else {
+      this.expand();
+    }
+  }
+
+  dispatchToggleEvent(action) {
+    return this.element.dispatchEvent(
+      new CustomEvent('toggle', {
+        bubbles: true,
+        cancelable: true,
+        detail: {
+          action: action
+        }
+      })
+    );
+  }
+
+  disableToggle() {
+    this.controlElement.setAttribute('aria-disabled', true);
+  }
+
+  enableToggle() {
+    this.controlElement.removeAttribute('aria-disabled');
+  }
+
+  addRegionId(regionId) {
+    const ids = this.regionIds;
+    if(!ids.find(id => regionId === id)) {
+      ids.push(regionId);
+      this.controlElement.setAttribute('aria-controls', ids.join(' '));
+    }
+  }
+
+  addRegionElement(region) {
+    if(!(region.classList.contains(COLLAPSIBLE_GROUP_CLASS) ||
+      region.classList.contains(COLLAPSIBLE_REGION_CLASS))) {
+      region.classList.add(COLLAPSIBLE_GROUP_CLASS);
+    }
+
+    if(!region.hasAttribute('role')) {
+      const role = region.classList.contains(COLLAPSIBLE_GROUP_CLASS) ? 'group' : 'region';
+      region.setAttribute('role', role);
+    }
+
+    if(!region.hasAttribute('id')) {
+      region.id = `${region.getAttribute('role')}-${randomString()}`;
+    }
+
+    if(this.isExpanded) {
+      region.removeAttribute('hidden');
+    }
+    else {
+      region.setAttribute('hidden', '');
+    }
+    this.addRegionId(region.id);
+  }
+
+  removeRegionElement(region) {
+    if(region && region.id) {
+      const ids = this.regionIds.filter(id => id === region.id);
+      this.controlElement.setAttribute('aria-controls', ids.join(' '));
+    }
+  }
+
+  removeListeners() {
+    this.controlElement.removeEventListener('keydown', this.keyDownHandler);
+    this.controlElement.removeEventListener('click', this.clickHandler);
+  }
+
+  init() {
+    const initControl = () => {
+      // Find the button element
+      this.controlElement_ = this.element.querySelector(`.${COLLAPSIBLE_CONTROL_CLASS}`) || this.element;
+
+      // Add "aria-expanded" attribute if not present
+      if(!this.controlElement.hasAttribute('aria-expanded')) {
+        this.controlElement.setAttribute('aria-expanded', 'false');
+      }
+
+      // Add role=button if control != <button>
+      if(this.controlElement.nodeName.toLowerCase() !== 'button') {
+        this.controlElement.setAttribute('role', 'button');
+      }
+
+      // Add tabindex
+      if(!isFocusable(this.controlElement) && !this.controlElement.hasAttribute('tabindex')) {
+        this.controlElement.setAttribute('tabindex', '0');
+      }
+    };
+
+    const initRegions = () => {
+      let regions = [];
+      if(!this.controlElement.hasAttribute('aria-controls')) {
+        // Add siblings as collapsible region(s)
+        let r = this.element.nextElementSibling;
+        while(r) {
+          if(r.classList.contains(COLLAPSIBLE_GROUP_CLASS) ||
+            r.classList.contains(COLLAPSIBLE_REGION_CLASS)) {
+            regions.push(r);
+          }
+          else if(r.classList.contains(JS_COLLAPSIBLE)) {
+            // A new collapsible component
+            break;
+          }
+          r = r.nextElementSibling;
+        }
+      }
+      else {
+        regions = this.regionElements;
+      }
+      regions.forEach(region => this.addRegionElement(region));
+    };
+
+    const addListeners = () => {
+      this.controlElement.addEventListener('keydown', this.keyDownHandler);
+      this.controlElement.addEventListener('click', this.clickHandler);
+    };
+
+    initControl();
+    initRegions();
+    this.removeListeners();
+    addListeners();
+  }
+
+  downgrade() {
+    this.removeListeners();
+  }
+
+}
+
+(function() {
+  'use strict';
+
+  /**
+   * @constructor
+   * @param {HTMLElement} element The element that will be upgraded.
+   */
+  const MaterialExtCollapsible = function MaterialExtCollapsible(element) {
+    this.element_ = element;
+    this.collapsible = null;
+
+    // Initialize instance.
+    this.init();
+  };
+  window['MaterialExtCollapsible'] = MaterialExtCollapsible;
+
+  /**
+   * Initialize component
+   */
+  MaterialExtCollapsible.prototype.init = function() {
+    if (this.element_) {
+      this.collapsible = new Collapsible(this.element_);
+      this.element_.classList.add(IS_UPGRADED);
+
+      // Listen to 'mdl-componentdowngraded' event
+      this.element_.addEventListener('mdl-componentdowngraded', this.mdlDowngrade_.bind(this));
+    }
+  };
+
+  /*
+   * Downgrade component
+   * E.g remove listeners and clean up resources
+   */
+  MaterialExtCollapsible.prototype.mdlDowngrade_ = function() {
+    this.collapsible.downgrade();
+  };
+
+
+  // Public methods.
+
+  /**
+   * Get control element.
+   * @return {HTMLElement} element The element that controls the collapsible region.
+   * @public
+   */
+  MaterialExtCollapsible.prototype.getControlElement = function() {
+    return this.collapsible.controlElement;
+  };
+  MaterialExtCollapsible.prototype['getControlElement'] = MaterialExtCollapsible.prototype.getControlElement;
+
+  /**
+   * Get region elements controlled by this collapsible
+   * @returns {Array<HTMLElement>} the collapsible region elements
+   * @public
+   */
+  MaterialExtCollapsible.prototype.getRegionElements = function() {
+    return this.collapsible.regionElements;
+  };
+  MaterialExtCollapsible.prototype['getRegionElements'] = MaterialExtCollapsible.prototype.getRegionElements;
+
+  /**
+   * Add region elements.
+   * @param {Array<HTMLElement>} elements The element that will be upgraded.
+   * @return {void}
+   * @public
+   */
+  MaterialExtCollapsible.prototype.addRegionElements = function(...elements) {
+    elements.forEach(element => this.collapsible.addRegionElement(element));
+  };
+  MaterialExtCollapsible.prototype['addRegionElements'] = MaterialExtCollapsible.prototype.addRegionElements;
+
+  /**
+   * Remove collapsible region(s) from component.
+   * Note: This operation does not delete the element from the DOM tree.
+   * @param {Array<HTMLElement>} elements The element that will be upgraded.
+   * @public
+   */
+  MaterialExtCollapsible.prototype.removeRegionElements = function(...elements) {
+    elements.forEach(element => this.collapsible.removeRegionElement(element));
+  };
+  MaterialExtCollapsible.prototype['removeRegionElements'] = MaterialExtCollapsible.prototype.removeRegionElements;
+
+  /**
+   * Expand collapsible region(s)
+   * @return {void}
+   * @public
+   */
+  MaterialExtCollapsible.prototype.expand = function() {
+    this.collapsible.expand();
+  };
+  MaterialExtCollapsible.prototype['expand'] = MaterialExtCollapsible.prototype.expand;
+
+  /**
+   * Collapse collapsible region(s)
+   * @return {void}
+   * @public
+   */
+  MaterialExtCollapsible.prototype.collapse = function() {
+    this.collapsible.collapse();
+  };
+  MaterialExtCollapsible.prototype['collapse'] = MaterialExtCollapsible.prototype.collapse;
+
+  /**
+   * Toggle collapsible region(s)
+   * @return {void}
+   * @public
+   */
+  MaterialExtCollapsible.prototype.toggle = function() {
+    this.collapsible.toggle();
+  };
+  MaterialExtCollapsible.prototype['toggle'] = MaterialExtCollapsible.prototype.toggle;
+
+  /**
+   * Check whether component has aria-expanded state true
+   * @return {Boolean} true if aria-expanded="true", otherwise false
+   */
+  MaterialExtCollapsible.prototype.isExpanded = function() {
+    return this.collapsible.isExpanded;
+  };
+  MaterialExtCollapsible.prototype['isExpanded'] = MaterialExtCollapsible.prototype.isExpanded;
+
+  /**
+   * Check whether component has aria-disabled state set to true
+   * @return {Boolean} true if aria-disabled="true", otherwise false
+   */
+  MaterialExtCollapsible.prototype.isDisabled = function() {
+    return this.collapsible.isDisabled;
+  };
+  MaterialExtCollapsible.prototype['isDisabled'] = MaterialExtCollapsible.prototype.isDisabled;
+
+  /**
+   * Disables toggling of collapsible region(s)
+   * @return {void}
+   * @public
+   */
+  MaterialExtCollapsible.prototype.disableToggle = function() {
+    this.collapsible.disableToggle();
+  };
+  MaterialExtCollapsible.prototype['disableToggle'] = MaterialExtCollapsible.prototype.disableToggle;
+
+  /**
+   * Enables toggling of collapsible region(s)
+   * @return {void}
+   * @public
+   */
+  MaterialExtCollapsible.prototype.enableToggle = function() {
+    this.collapsible.enableToggle();
+  };
+  MaterialExtCollapsible.prototype['enableToggle'] = MaterialExtCollapsible.prototype.enableToggle;
+
+  // The component registers itself. It can assume componentHandler is available
+  // in the global scope.
+  /* eslint no-undef: 0 */
+  componentHandler.register({
+    constructor: MaterialExtCollapsible,
+    classAsString: 'MaterialExtCollapsible',
+    cssClass: JS_COLLAPSIBLE,
+    widget: true
+  });
+
+})();
diff --git a/node_modules/mdl-ext/src/collapsible/readme.md b/node_modules/mdl-ext/src/collapsible/readme.md
new file mode 100644
index 0000000..553e48a
--- /dev/null
+++ b/node_modules/mdl-ext/src/collapsible/readme.md
@@ -0,0 +1,467 @@
+# Collapsible
+
+**Collapsed**
+
+![Collapsible collapsed](../../etc/collapsible-collapsed.jpg)
+
+**Expanded**
+
+![Collapsible expanded](../../etc/collapsible-expanded.jpg)
+
+A collapsible is a component to mark expandable and collapsible regions. It has 
+states, roles, attributes and behaviour in accordance with guidelines given in 
+[Using the WAI-ARIA aria-expanded state to mark expandable and collapsible regions](https://www.w3.org/WAI/GL/wiki/Using_the_WAI-ARIA_aria-expanded_state_to_mark_expandable_and_collapsible_regions),
+[ARIA Authoring Practices, Button](https://www.w3.org/TR/wai-aria-practices-1.1/#button), 
+and [Building Accessible Buttons with ARIA: A11y](http://www.deque.com/blog/accessible-aria-buttons/)
+
+## Collapse All the Things
+The collapsible acts as a "pluggable" component. It uses a `<button>` element or 
+an element with `role="button"` to control one or more collapsible regions. You 
+can make virtually any HTML element collapsible by adding two classes, 
+`mdlext-js-collapsible` to the element that should control the collapsible 
+region(s), and one of the classes `mdlext-collapsible-group` or 
+`mdlext-collapsible-region` to the element that should collapse/expand. The 
+collapsible component uses the 
+[aria-controls](https://www.w3.org/TR/wai-aria/states_and_properties#aria-controls) 
+property to hold a list of one or more collapsible regions. The 
+[aria-expanded](https://www.w3.org/TR/wai-aria/states_and_properties#aria-expanded) 
+state indicates whether region(s) controlled by the component is currently 
+expanded or collapsed.
+
+## To include a MDLEXT collapsible component:
+&nbsp;1. Code a `<button>` element; this is the clickable toggle that will show and hide the collapsible 
+region(s). Inside the button, code a `<span>` element to hold the button caption text.
+
+```html
+<button>
+  <span>Click to toggle</span>
+</button>
+```
+
+&nbsp;2. Add the `mdlext-js-collapsible` class to define the element as a collapsible component.
+
+```html
+<button class="mdlext-js-collapsible">
+  <span>Click to toggle</span>
+</button>
+```
+
+&nbsp;3. Optionally add the `mdlext-collapsible` class, which will add a pointer 
+cursor to the collapsible component.
+
+```html
+<button class="mdlext-js-collapsible mdlext-collapsible">
+  <span>Click to toggle</span>
+</button>
+```
+
+&nbsp;4. Optionally add a state icon. Code a `<i>` element with class 
+`mdlext-aria-expanded-more-less`. The state icon should indicate whether the 
+collapsible region is expanded or not.
+
+```html
+<button class="mdlext-js-collapsible">
+  <span>Click to toggle</span>
+  <i class="mdlext-aria-expanded-more-less"></i>
+</button>
+```
+
+&nbsp;5. Code a `<div>` element with class `mdlext-collapsible-group` or
+`mdlext-collapsible-region` to define the element as a collapsible region. 
+
+```html
+<div class="mdlext-collapsible-group">
+</div>
+```
+
+&nbsp;6. Add content inside the collapsible container. 
+
+```html
+<div class="mdlext-collapsible-group">
+  <p>Content goes here ...</p>
+</div>
+```
+
+After page load, the component will add all required Aria states, roles and 
+attributes not already present in markup. 
+
+```html
+<button class="mdlext-js-collapsible is-upgraded" 
+  data-upgraded=",MaterialExtCollapsible" 
+  aria-expanded="false" aria-controls="group-4ek31z6jeeag">
+  <span>Click to toggle</span>
+  <i class="mdlext-aria-expanded-more-less"></i>
+</button>
+<div class="mdlext-collapsible-group" id="group-4ek31z6jeeag" role="group" hidden>
+  <p>Content goes here ...</p>
+</div>
+```
+
+Instead of letting the collapsible component add all the WAI-ARIA stuff, 
+add it yourself in markup. The component will not override attributes already 
+present in markup.
+
+```html
+<div class="mdlext-js-collapsible" role="button" 
+  aria-expanded="false" aria-controls="group-1">
+  <span>Click to toggle</span>
+  <i class="mdlext-aria-expanded-more-less"></i>
+</div>
+<div class="mdlext-collapsible-group" id="group-1" role="group" hidden>
+  <p>Content Region #1 goes here ...</p>
+</div>
+```
+
+### role="group" vs role="region"
+The group role is used to identify a set of user interface objects which, in 
+contrast with a region, are not intended to be included in a table of contents 
+or a page summary (such as the structures that are dynamically created by a 
+script or assistive technologies); a group should not be considered a major 
+perceivable section on a page. When the role is added to an element, the browser 
+will send out an accessible group event to assistive technology products which 
+can then notify the user about it.
+
+To define an element as collapsible add one of the classes  
+`mdlext-collapsible-group` or `mdlext-collapsible-region`. The component will
+set the role attribute to `group` or `region` accordingly.
+
+[Group](https://www.w3.org/TR/wai-aria/roles#group): A set of user interface
+objects which are not intended to be included in a page summary or table of 
+contents by assistive technologies.
+
+[Region](https://www.w3.org/TR/wai-aria/roles#region): A large perceivable 
+section of a web page or document, that is important enough to be included in a 
+page summary or table of contents, for example, an area of the page containing 
+live sporting event statistics. 
+
+### Use a `<div>` element as a collapsible component.
+It's easier to style a div compared to a button. For example, you can not style 
+a button as a flexible box! 
+ 
+```html
+<div class="mdlext-js-collapsible mdlext-collapsible" aria-expanded="true">
+  <span>Click to toggle</span>
+  <i class="mdlext-aria-expanded-more-less"></i>
+</div>
+<div class="mdlext-collapsible-region">
+  <p>Content goes here ...</p>
+</div>
+```
+
+For further control with styling, it is possible to wrap the button element 
+inside the collapsible component. The wrapped element becomes the clickable/focusable
+area and **must** have class `mdlext-collapsible` applied.
+
+```html
+<header class="mdlext-js-collapsible" aria-expanded="true">
+  <div class="mdlext-collapsible"> 
+    <span>Click to toggle</span>
+    <i class="mdlext-aria-expanded-more-less"></i>
+  </div>  
+</header>
+<div class="mdlext-collapsible-region">
+  <p>Content goes here ...</p>
+</div>
+```
+
+### one-to-many
+You can create a one-to-many relationship by supplying a space separated list of 
+ids, representing different, simultaneously controlled elements.
+
+```html
+<div class="medext-js-collapsible">
+  <div class="mdlext-collapsible" role="button" 
+    aria-controls="collapsible-1 collapsible-3">A topic</div>
+</div>
+
+<div id="collapsible-1" class="mdlext-collapsible-group">
+  <p>Topic 1 is all about being Topic 1 and may or 
+  may not have anything to do with other topics.</p>
+</div>
+
+<div id="collapsible-2" class="mdlext-collapsible-group">
+  <p>Topic 2 is all about being Topic 2 and may or 
+  may not have anything to do with other topics.</p>
+</div>
+
+<div id="collapsible-3" class="mdlext-collapsible-group">
+  <p>Topic 3 is all about being Topic 3 and may or 
+  may not have anything to do with other topics.</p>
+</div>
+```
+
+If the `aria-controls` attribute is provided in markup, the component will not 
+attempt to determine corresponding collapsible regions. In the markup above,
+only `collapsible-1` and `collapsible-3` will be controlled by the component.
+
+Remove the `aria-controls` attribute if you want the component to determine the 
+collapsible regions to be included.
+
+### Examples
+
+**Collapsibles, with many collapsible regions.**
+
+```html
+<!-- first collapsible -->
+<button class="mdlext-js-collapsible mdlext-collapsible">
+  <span>Click to toggle collapsible #1</span>
+  <i class="mdlext-aria-expanded-more-less"></i>
+</button>
+<div class="mdlext-collapsible-region">
+  <p>#1.1</p>
+</div>
+<div class="mdlext-collapsible-region">
+  <p>#1.2</p>
+</div>
+
+<!-- second collapsible -->
+<header class="mdlext-js-collapsible mdlext-collapsible">
+  <span>Click to toggle collapsible #2</span>
+  <i class="mdlext-aria-expanded-more-less"></i>
+</header>
+<div class="mdlext-collapsible-region">
+  <p>#2.1</p>
+</div>
+
+<p>This paragraph will not collapse</p>
+
+<div class="mdlext-collapsible-region">
+  <p>#2.2</p>
+</div>
+<div class="mdlext-collapsible-region">
+  <p>#2.3</p>
+</div>
+```
+
+**Nested collapsibles.**
+
+```html
+<style>
+  .mdlext-collapsible-region .mdlext-js-collapsible,
+  .mdlext-collapsible-region .mdlext-collapsible-region {
+    margin-left: 16px;
+  }
+</style>
+
+<button class="mdlext-js-collapsible mdl-button mdl-button--colored mdl-button--raised">
+  Click to toggle
+</button>
+<div class="mdlext-collapsible-region">
+  <p>A collapsible region</p>
+
+  <button class="mdlext-js-collapsible mdl-button mdl-button--accent mdl-button--raised">
+    Click to toggle nested #1
+  </button>
+  <div class="mdlext-collapsible-region">
+    <p>A nested collapsible region</p>
+
+    <button class="mdlext-js-collapsible mdl-button mdl-button--raised 
+      mdl-button--colored mdl-color--deep-orange-100">
+      Click to toggle nested #2
+    </button>
+    <div class="mdlext-collapsible-region">
+      <p>Last region</p>
+    </div>
+  </div>
+</div>
+```
+
+**Collapsible MDL Card.**
+
+```html
+<!-- The card need some styling to act as a collapsible -->
+<style>
+  .mdl-card.welcome-card {
+    min-height: 0;
+    max-width: 640px;
+    width: auto;
+  }
+  .mdl-card.welcome-card > .mdl-card__title {
+    -webkit-box-pack: start;
+    -webkit-justify-content: flex-start;
+    -ms-flex-pack: start;
+    justify-content: flex-start;
+    height: 176px;
+    min-height: 64px;
+    padding-top: 0;
+    padding-bottom: 0;
+    color: #fff;
+    background: url('./assets/welcome_card.jpg') top / cover;
+  }
+  .mdl-card.welcome-card .mdl-card__title:focus {
+    /* Must focus ring must be inside title since mdl-card has overflow:hidden */
+    outline-offset: -4px;
+  }
+  .mdl-card.welcome-card .mdl-card__title > * {
+    -webkit-align-self: center;
+    -ms-flex-item-align: center;
+    align-self: center;
+  }
+  .mdl-card.welcome-card .mdl-card__supporting-text {
+    width: auto;
+  }
+  .mdl-card.welcome-card .mdl-card__actions {
+    display: -webkit-box;
+    display: -webkit-flex;
+    display: -ms-flexbox;
+    display: flex;
+  }
+  .welcome-card > .mdl-card__title .mdl-card__title-text {
+    -webkit-align-self: flex-end;
+    -ms-flex-item-align: end;
+    align-self: flex-end;
+    padding-bottom: 16px;
+  }
+  .welcome-card > .mdl-card__title[aria-expanded='false'] {
+    height: 64px;
+  }
+  .welcome-card > .mdl-card__title[aria-expanded='false'] .mdl-card__title-text {
+    -webkit-align-self: center;
+    -ms-flex-item-align: center;
+    align-self: center;
+    padding-bottom: 0;
+  }
+  .welcome-card > .mdl-card__menu {
+    color: #ffffff;
+  }
+</style>
+
+<div class="welcome-card mdl-card mdl-shadow--2dp">
+  <header class="mdl-card__title mdlext-js-collapsible mdlext-collapsible">
+    <h2 class="mdl-card__title-text">A Collapsible Card</h2>
+  </header>
+  <section class="mdl-card__supporting-text mdlext-collapsible-region">
+    Lorem ipsum dolor sit amet, consectetur adipiscing elit.
+    Mauris sagittis pellentesque lacus eleifend lacinia...
+  </section>
+  <footer class="mdl-card__actions mdl-card--border mdlext-collapsible-region">
+    <button class="mdl-button mdl-button--colored mdl-js-button mdl-js-ripple-effect">
+      Get Started
+    </button>
+  </footer>
+  <div class="mdl-card__menu">
+    <button class="mdl-button mdl-button--icon mdl-js-button mdl-js-ripple-effect">
+      <i class="material-icons">share</i>
+    </button>
+  </div>
+</div>
+```
+
+**Create your own state icon with SASS.**
+
+The [_mixins.scss](../_mixins.scss) has a mixin which can be used to create custom state icons.  
+
+```sass
+@charset "UTF-8";
+.my-aria-expanded-state {
+  @include mdlext-aria-expanded-toggle($icon: 'arrow_downward', $icon-expanded: 'arrow_upward');
+}
+```
+
+### More examples
+* The [snippets/collapsible.html](./snippets/collapsible.html) and the [tests](../../test/collapsible/collapsible.spec.js) provides more detailed examples.
+* Try out the [live demo](http://leifoolsen.github.io/mdl-ext/demo/collapsible.html)
+
+## Characteristics
+
+### Keyboard interaction 
+* <kbd>Space</kbd> or <kbd>Enter</kbd>: toggle the corresponding collapsible region(s).
+
+### Mouse interaction 
+* <kbd>Click</kbd>: toggle the corresponding collapsible region(s).
+    
+## Events
+The collapsible component emits a custom `toggle` event when the component is clicked, 
+<kbd>Enter</kbd> key or <kbd>Space</kbd> key is pressed or one of the methods `expand`. 
+`collapse` or `toggle` is called. The event is emitted before the actual toggling 
+occurs. Call `event.preventDefault()` to cancel toggling.
+
+The detail object parameter has the following structure:
+```javascript
+detail: {
+  action // 'expand' or collapse'  
+}
+```
+Set up an event listener to receive the toggle event.
+```javascript
+var someCondition = false;
+document.querySelector('#my-collapsible').addEventListener('toggle', function(e) {
+  console.log('Toggle action:', e.detail.action);
+  if(someCondition) {
+    // Stop toggling
+    e.preventDefault();
+  }
+  someCondition = !someCondition;
+});
+```
+
+## Public methods
+
+### getControlElement()
+Get the element that controls the collapsible region(s).
+
+### getRegionElements()
+Get region elements controlled by this collapsible.
+
+### addRegionElements(...elements)
+Add collapsible region(s).
+
+### removeRegionElements(...elements)
+Remove collapsible region(s).
+
+### expand()
+Expand corresponding collapsible region(s).
+
+### collapse()
+Collapse corresponding collapsible region(s).
+
+### toggle()
+Toggle corresponding collapsible region(s).
+```javascript
+const component = document.querySelector('#my-collapsible');
+component.MaterialExtCollapsible.toggle();
+```
+### isExpanded()
+Check whether component has aria-expanded state set to true.
+
+### isDisabled()
+Check whether component has aria-disabled state set to true.
+
+### enableToggle()
+Enables toggling of collapsible region(s).
+
+### disableToggle()
+Disables toggling of collapsible region(s).
+
+## Configuration options
+The MDLEXT CSS classes apply various predefined visual and behavioral enhancements to the accordion. 
+
+### Available classes and their effects.
+
+| MDLEXT class | Effect | Remarks |
+|--------------|--------|---------|
+|`mdlext-js-collapsible`| Assigns basic MDL behavior to collapsible. | Required. |
+|`mdlext-collapsible`| Defines container as an MDL component. | Optional. |
+|`mdlext-collapsible-group`| Defines container as a collapsible group. | Required. Either `mdlext-collapsible-group` or `mdlext-collapsible-region` must be present to make a container collapsible. |
+|`mdlext-collapsible-region`| Defines container as a collapsible region. | Required. |
+
+### Available WAI-ARIA roles, states, and properties
+
+| Attribute | Description | Remarks |
+|-----------|-------------|---------|
+|`role="button`| The element that toggles a region has role [button](http://www.w3.org/TR/wai-aria-1.1/#button). | Added by component if not present |
+|`tabindex`| Indicates whether an element is focusable. | A value less than 0, e.g. -1, indicates that the element is not focusable. Tabindex="0" added by component if not present |
+|`aria-controls`| Identfies the content on the page, using IDREFs, that this collapsible controls. | Added by component if not present. |
+|`aria-expanded`| The element with role `button` has [aria-expanded](https://www.w3.org/TR/wai-aria-1.1/#aria-expanded) set to `true` if the corresponding region(s) is open, oterwise false. | Defaults to `aria-expanded="false"`. Set `aria-expanded="true"` if you want a region to open during page load. |
+|`aria-disabled`| When a collapsible should not be toggable, set `aria-disabled` to `true`. | Optional. If this attribute is present, the collapsible region(s) will not toggle. |
+|`disabled`| Indicates that a collapsible component and it's corresponding region(s) is disabled, otherwise not present. | Optional. If this attribute is present, the collapsible regions will not toggle. |
+|`role="group`| Identifies an element as a collapsible [group](https://www.w3.org/TR/wai-aria/roles#group). | Required on container with class `mdlext-collapsible-group`. Added by component if not present. |
+|`role="region`| Identifies an element as a collapsible [region](https://www.w3.org/TR/wai-aria/roles#region). | Required on container with class `mdlext-collapsible-region`. Added by component if not present. |
+|`hidden`| Visually hides a collapsible region. | Added by component if component has `aria-expanded="false"`. |
+|`id`| The collapsible region must have an id. | A random id is added if not present. The IDREF is used by the `aria-controls` attribute to identify the collapsible region. |
+
+## Other collapsible examples
+* [ARIA Examples, Progressive collapsibles](http://heydonworks.com/practical_aria_examples/#progressive-collapsibles)
+* [Open Ajax, Example 20 - Hide/Show: Region follows button](http://oaa-accessibility.org/example/20/)
+* [Open Ajax, Example 21 - Hide/Show: Region does not follow button](http://oaa-accessibility.org/example/21/)
+* [Open Ajax, Example 22 - Hide/Show: Region is exclusive](http://oaa-accessibility.org/example/22/)
diff --git a/node_modules/mdl-ext/src/collapsible/snippets/collapsible.html b/node_modules/mdl-ext/src/collapsible/snippets/collapsible.html
new file mode 100644
index 0000000..f959654
--- /dev/null
+++ b/node_modules/mdl-ext/src/collapsible/snippets/collapsible.html
@@ -0,0 +1,237 @@
+<p>A collapsible is a component to mark expandable and collapsible regions.
+  It has states, roles, attributes and behavior in accordance with guidelines given in
+  <a href="https://www.w3.org/WAI/GL/wiki/Using_the_WAI-ARIA_aria-expanded_state_to_mark_expandable_and_collapsible_regions">
+    Using the WAI-ARIA aria-expanded state to mark expandable and collapsible regions
+  </a>.
+</p>
+<article>
+  <button class="mdlext-js-collapsible" style="padding: 8px;">
+    <span>Click to toggle (button)</span>
+    <i class="mdlext-aria-expanded-more-less"></i>
+  </button>
+  <div class="mdlext-collapsible-group"><p>A collapsible region #1.1</p></div>
+  <div class="mdlext-collapsible-group"><p>A collapsible region #1.2</p></div>
+  <div class="mdlext-collapsible-group"><p>A collapsible region #1.3</p></div>
+</article>
+
+<article style="margin-top: 16px;">
+  <div class="mdlext-js-collapsible mdlext-collapsible" style="padding: 8px;">
+    <span>Click to toggle (div)</span>
+    <i class="mdlext-aria-expanded-more-less"></i>
+  </div>
+  <div class="mdlext-collapsible-region"><p>A collapsible region #2.1</p></div>
+  <div class="mdlext-collapsible-region"><p>A collapsible region #2.2</p></div>
+  <div class="mdlext-collapsible-region"><p>A collapsible region #2.3</p></div>
+</article>
+
+
+<style>
+  .mdl-card.demo-card,
+  .mdl-card.welcome-card {
+    min-height: 0;
+    width: auto;
+    margin-top: 16px;
+    margin-bottom: 16px;
+    max-width: 640px;
+  }
+  .mdl-card.demo-card .mdl-card__media,
+  .mdl-card.welcome-card .mdl-card__media {
+    margin: 0;
+    text-align: center;
+  }
+  .mdl-card.demo-card .mdl-card__media > img,
+  .mdl-card.welcome-card .mdl-card__media > img {
+    max-width: 100%;
+    height: auto;
+  }
+  .mdl-card.demo-card .mdl-card__title,
+  .mdl-card.welcome-card .mdl-card__title {
+    /* Fix bug in _card.scss */
+    -webkit-box-pack: start;
+    -webkit-justify-content: flex-start;
+    -ms-flex-pack: start;
+    justify-content: flex-start;
+    /* end fix */
+
+    padding-top: 0;
+    padding-bottom: 0;
+    min-height: 64px;
+  }
+  .mdl-card.demo-card .mdl-card__title:focus,
+  .mdl-card.welcome-card .mdl-card__title:focus {
+    /* Must focus ring must be inside title since mdl-card has overflow:hidden */
+    outline-offset: -4px;
+  }
+  .mdl-card.demo-card .mdl-card__title > *,
+  .mdl-card.welcome-card .mdl-card__title > * {
+    -webkit-align-self: center;
+    -ms-flex-item-align: center;
+    align-self: center;
+  }
+  .mdl-card.demo-card .mdl-card__supporting-text,
+  .mdl-card.welcome-card .mdl-card__supporting-text {
+    width: auto;
+  }
+  .mdl-card.demo-card .mdl-card__actions,
+  .mdl-card.welcome-card .mdl-card__actions {
+    display: -webkit-box;
+    display: -webkit-flex;
+    display: -ms-flexbox;
+    display: flex;
+  }
+  .welcome-card > .mdl-card__title {
+    color: #fff;
+    height: 176px;
+    background: url('./assets/welcome_card.jpg') top / cover;
+  }
+  .welcome-card > .mdl-card__title[aria-expanded='false'] {
+    height: 64px;
+  }
+  .welcome-card > .mdl-card__title .mdl-card__title-text {
+    -webkit-align-self: flex-end;
+    -ms-flex-item-align: end;
+    align-self: flex-end;
+    padding-bottom: 16px;
+  }
+  .welcome-card > .mdl-card__title[aria-expanded='false'] .mdl-card__title-text {
+    -webkit-align-self: center;
+    -ms-flex-item-align: center;
+    align-self: center;
+    padding-bottom: 0;
+  }
+  .welcome-card > .mdl-card__menu {
+    color: #fff;
+  }
+
+  table.info {
+    width: 100%
+  }
+  table.info th {
+    padding-right: 40px;
+    vertical-align: middle;
+    text-align: left;
+    width: 120px;
+  }
+</style>
+
+<div class="welcome-card mdl-card mdl-shadow--2dp">
+  <header class="mdl-card__title mdlext-js-collapsible mdlext-collapsible" aria-expanded="true">
+    <h2 class="mdl-card__title-text">A Collapsible Card</h2>
+  </header>
+  <section class="mdl-card__supporting-text mdlext-collapsible-group">
+    Lorem ipsum dolor sit amet, consectetur adipiscing elit.
+    Mauris sagittis pellentesque lacus eleifend lacinia...
+  </section>
+  <footer class="mdl-card__actions mdl-card--border mdlext-collapsible-group">
+    <button class="mdl-button mdl-button--colored mdl-js-button mdl-js-ripple-effect">
+      Get Started
+    </button>
+  </footer>
+  <div class="mdl-card__menu">
+    <button class="mdl-button mdl-button--icon mdl-js-button mdl-js-ripple-effect">
+      <i class="material-icons">share</i>
+    </button>
+  </div>
+</div>
+
+
+<style>
+  .mdlext-collapsible-group .mdlext-js-collapsible,
+  .mdlext-collapsible-group .mdlext-collapsible-group {
+    margin-left: 16px;
+  }
+</style>
+
+<button class="mdlext-js-collapsible mdl-button mdl-button--colored mdl-button--raised">Click to toggle</button>
+<div class="mdlext-collapsible-group">
+  <p>A collapsible region</p>
+
+  <button class="mdlext-js-collapsible mdl-button mdl-button--accent mdl-button--raised">Click to toggle nested #1</button>
+  <div class="mdlext-collapsible-group">
+    <p>A nested collapsible region</p>
+
+    <button class="mdlext-js-collapsible mdl-button mdl-button--colored mdl-color--deep-orange-100 mdl-button--raised">Click to toggle nested #2</button>
+    <div class="mdlext-collapsible-group">
+      <p>Last region</p>
+    </div>
+  </div>
+</div>
+
+
+<div id="another-card" class="mdl-card demo-card mdl-shadow--2dp mdlext-dark-color-theme">
+  <header class="mdl-card__title mdl-color--primary mdl-color-text--primary-contrast mdlext-js-collapsible mdlext-collapsible">
+    <button class="mdl-button mdl-button--icon mdl-js-button mdl-js-ripple-effect">
+      <i class="material-icons">view_headline</i>
+    </button>
+    <h2 class="mdl-card__title-text">Another collapsible card</h2>
+    <div class="mdl-layout-spacer"></div>
+    <i class="material-icons md-36 mdlext-aria-expanded-more-less"></i>
+  </header>
+  <figure class="mdl-card__media mdlext-collapsible-region">
+    <img src="./images/_DSC7535-2.jpg" alt="">
+  </figure>
+  <section style="margin-top:16px" class="mdl-card__supporting-text mdlext-collapsible-region">
+    <table class="info">
+      <tr>
+        <th class="mdl-typography--caption-color-contrast">primary-dark</th>
+        <td class="mdl-color--primary-dark mdl-color-text--primary-contrast">primary dark</td>
+      </tr>
+      <tr>
+        <th class="mdl-typography--caption-color-contrast">primary</th>
+        <td class="mdl-color--primary mdl-color-text--primary-contrast">primary</td>
+      </tr>
+      <tr>
+        <th class="mdl-typography--caption-color-contrast">accent</th>
+        <td class="mdl-color--accent mdl-color-text--accent-contrast">accent</td>
+      </tr>
+      <tr>
+        <th class="mdl-typography--caption-color-contrast">primary-dark</th>
+        <td class="mdl-color--primary-contrast mdl-color-text--primary-dark">primary dark, inverted</td>
+      </tr>
+      <tr>
+        <th class="mdl-typography--caption-color-contrast">primary</th>
+        <td class="mdl-color--primary-contrast mdl-color-text--primary">primary, inverted</td>
+      </tr>
+      <tr>
+        <th class="mdl-typography--caption-color-contrast">accent</th>
+        <td class="mdl-color--accent-contrast mdl-color-text--accent">accent, inverted</td>
+      </tr>
+    </table>
+  </section>
+
+  <div class="mdl-card__supporting-text mdlext-collapsible-region">
+    Card Supporting Text
+  </div>
+
+  <footer class="mdl-card__actions mdl-card--border">
+    <button id="read-more" class="mdl-button mdl-button--colored mdl-js-button mdl-js-ripple-effect">
+      Read more
+    </button>
+    <div class="mdl-layout-spacer"></div>
+    <button class="mdl-button mdl-button--icon"><i class="material-icons">radio</i></button>
+    <button class="mdl-button mdl-button--icon mdl-button--colored"><i class="material-icons">favorite</i></button>
+    <button class="mdl-button mdl-button--icon mdl-button--colored"><i class="material-icons">share</i></button>
+  </footer>
+</div>
+
+
+
+<script>
+  (function() {
+    'use strict';
+    window.addEventListener('load', function() {
+
+      document.querySelector('#read-more').addEventListener('click', function (e) {
+        var collapsible = document.querySelector('#another-card .mdlext-js-collapsible');
+        collapsible.MaterialExtCollapsible.expand();
+      });
+
+      document.querySelector('#another-card').addEventListener('toggle', function (e) {
+        console.log('Toggle action:', e.detail.action);
+      });
+
+    });
+
+  }());
+
+</script>
diff --git a/node_modules/mdl-ext/src/color-themes/_color-themes.scss b/node_modules/mdl-ext/src/color-themes/_color-themes.scss
new file mode 100644
index 0000000..6944941
--- /dev/null
+++ b/node_modules/mdl-ext/src/color-themes/_color-themes.scss
@@ -0,0 +1,57 @@
+/* -------------------------------------------------------------
+   Palette samples. Not part of build
+----------------------------------------------------------------
+
+$mdlext-light-color-primary:          #9E9E9E !default;
+$mdlext-light-color-primary-dark:     #616161 !default;
+$mdlext-light-color-primary-light:    #9E9E9E !default;  // Fallback color. Set to color-primary if fallback is not needed
+$mdlext-light-color-primary-contrast: #212121 !default;  // text color on primary/primary dark background
+$mdlext-light-color-accent:           #E040FB !default;
+$mdlext-light-color-accent-light:     #E040FB !default;  // Fallback color. Set to color-accent if fallback is not needed
+$mdlext-light-color-accent-contrast:  #FAFAFA !default;
+
+$mdlext-light-color-primary:          #F5F5F5 !default;
+$mdlext-light-color-primary-dark:     #E0E0E0 !default;
+$mdlext-light-color-primary-light:    #8BC34A !default;  // Fallback color. Set to color-primary if fallback is not needed
+$mdlext-light-color-primary-contrast: #000000 !default;  // text color on primary/primary dark background
+$mdlext-light-color-accent:           #FFC107 !default;
+$mdlext-light-color-accent-light:     #FFC107 !default;  // Fallback color. Set to color-accent if fallback is not needed
+$mdlext-light-color-accent-contrast:  #FFFFFF !default;
+
+
+$mdlext-light-color-primary:          #673AB7 !default;
+$mdlext-light-color-primary-dark:     #512DA8 !default;
+$mdlext-light-color-primary-light:    #673AB7 !default;   // Fallback color. Set to color-primary if fallback is not needed
+$mdlext-light-color-primary-contrast: #D1C4E9 !default;   // text color on primary/primary dark background
+$mdlext-light-color-accent:           #4CAF50 !default;
+$mdlext-light-color-accent-light:     #4CAF50 !default;   // Fallback color. Set to color-accent if fallback is not needed
+$mdlext-light-color-accent-contrast:  #FFFFFF !default;
+
+
+$mdlext-light-color-primary:          #4CAF50 !default;
+$mdlext-light-color-primary-dark:     #388E3C !default;
+$mdlext-light-color-primary-light:    #4CAF50 !default;  // Fallback color. Set to color-primary if fallback is not needed
+$mdlext-light-color-primary-contrast: #C8E6C9 !default;  // text color on primary/primary dark background
+$mdlext-light-color-accent:           #FF5252 !default;
+$mdlext-light-color-accent-light:     #FF5252 !default;  // Fallback color. Set to color-accent if fallback is not needed
+$mdlext-light-color-accent-contrast:  #FFFFFF !default;
+
+
+$mdlext-light-color-primary:          #4CAF50 !default;
+$mdlext-light-color-primary-dark:     #388E3C !default;
+$mdlext-light-color-primary-light:    #4CAF50 !default;  // Fallback color. Set to color-primary if fallback is not needed
+$mdlext-light-color-primary-contrast: #C8E6C9 !default;  // text color on primary/primary dark background
+$mdlext-light-color-accent:           #03A9F4 !default;
+$mdlext-light-color-accent-light:     #03A9F4 !default;  // Fallback color. Set to color-accent if fallback is not needed
+$mdlext-light-color-accent-contrast:  #FFFFFF !default;
+
+
+$mdlext-dark-color-primary:           #212121 !default;
+$mdlext-dark-color-primary-dark:      #000000 !default;
+$mdlext-dark-color-primary-light:     #607D8B !default;  // Fallback color. Set to color-primary if fallback is not needed
+$mdlext-dark-color-primary-contrast:  #FFFFFF !default;  // text color on primary/primary dark background
+$mdlext-dark-color-accent:            #FF5722 !default;
+$mdlext-dark-color-accent-light:      #FF5722 !default;  // Fallback color. Set to color-accent if fallback is not needed
+$mdlext-dark-color-accent-contrast:   #FFFFFF !default;
+
+*/
diff --git a/node_modules/mdl-ext/src/color-themes/_dark-color-theme.scss b/node_modules/mdl-ext/src/color-themes/_dark-color-theme.scss
new file mode 100644
index 0000000..954e19c
--- /dev/null
+++ b/node_modules/mdl-ext/src/color-themes/_dark-color-theme.scss
@@ -0,0 +1,1132 @@
+@import "color-themes";
+
+.mdlext-dark-color-theme {
+  background-color: $mdlext-dark-content-background-color;
+  color: $mdlext-dark-text-color-primary;
+  a {
+    outline-color: inherit;
+  }
+}
+
+// mdl/src/palette/_palette.scss
+.mdlext-dark-color-theme {
+
+  .mdl-color--primary {
+    background-color: $mdlext-dark-color-primary !important;
+  }
+
+  .mdl-color--primary-contrast {
+    background-color: $mdlext-dark-color-primary-contrast !important;
+  }
+
+  .mdl-color--primary-dark {
+    background-color: $mdlext-dark-color-primary-dark !important;
+  }
+
+  .mdl-color--accent {
+    background-color: $mdlext-dark-color-accent !important;
+  }
+
+  .mdl-color--accent-contrast {
+    background-color: $mdlext-dark-color-accent-contrast !important;
+  }
+
+  .mdl-color-text--primary {
+    color: $mdlext-dark-color-primary !important;
+  }
+
+  .mdl-color-text--primary-contrast {
+    color: $mdlext-dark-color-primary-contrast !important;
+  }
+
+  .mdl-color-text--primary-dark {
+    color: $mdlext-dark-color-primary-dark !important;
+  }
+
+  .mdl-color-text--accent {
+    color: $mdlext-dark-color-accent !important;
+  }
+
+  .mdl-color-text--accent-contrast {
+    color: $mdlext-dark-color-accent-contrast !important;
+  }
+
+}
+
+// mdl/src/typography/_typography.scss
+.mdlext-dark-color-theme {
+  a {
+    color: $mdlext-dark-text-link-color;
+  }
+}
+
+
+// mdl/src/badge/_badge.scss
+// ---------------------------
+.mdlext-dark-color-theme {
+  .mdl-badge {
+
+    &[data-badge]::after {
+      background: $mdlext-dark-badge-background;
+      color: $mdlext-dark-badge-color;
+    }
+
+    &.mdl-badge--no-background {
+      &[data-badge]::after {
+        color: $mdlext-dark-badge-color-inverse;
+        background: $mdlext-dark-badge-background-inverse;
+      }
+    }
+  }
+}
+
+
+// mdl/src/button/_button.scss
+// ---------------------------
+.mdlext-dark-color-theme {
+
+  .mdl-button {
+    background: transparent;
+    color: $mdlext-dark-button-secondary-color;
+
+    &:hover {
+      background-color: $mdlext-dark-button-hover-color;
+    }
+
+    &:focus:not(:active) {
+      background-color: $mdlext-dark-button-focus-color;
+    }
+
+    &:active {
+      background-color: $mdlext-dark-button-active-color;
+    }
+
+    &.mdl-button--colored {
+      color: $mdlext-dark-button-primary-color-alt;
+
+      &:focus:not(:active) {
+        background-color: $mdlext-dark-button-focus-color-alt;
+      }
+    }
+  }
+
+  // Raised buttons
+  .mdl-button--raised {
+    background: $mdlext-dark-button-primary-color;
+
+    &:active {
+      background-color: $mdlext-dark-button-active-color;
+    }
+
+    &:focus:not(:active) {
+      background-color: $mdlext-dark-button-active-color;
+    }
+
+    &.mdl-button--colored {
+      background: $mdlext-dark-button-primary-color-alt;
+      color: $mdlext-dark-button-secondary-color-alt;
+
+      &:hover {
+        background-color: $mdlext-dark-button-hover-color-alt;
+      }
+
+      &:active {
+        background-color: $mdlext-dark-button-active-color-alt;
+      }
+
+      &:focus:not(:active) {
+        background-color: $mdlext-dark-button-active-color-alt;
+      }
+
+      & .mdl-ripple {
+        background: $mdlext-dark-button-ripple-color-alt;
+      }
+    }
+  }
+
+
+  // FABs
+  .mdl-button--fab {
+    background: $mdlext-dark-button-primary-color;
+
+    &:active {
+      background-color: $mdlext-dark-button-active-color;
+    }
+
+    &:focus:not(:active) {
+      background-color: $mdlext-dark-button-active-color;
+    }
+
+    &.mdl-button--colored {
+      background: $mdlext-dark-button-fab-color-alt;
+      color: $mdlext-dark-button-fab-text-color-alt;
+
+      &:hover {
+        background-color: $mdlext-dark-button-fab-hover-color-alt;
+      }
+
+      &:focus:not(:active) {
+        background-color: $mdlext-dark-button-fab-active-color-alt;
+      }
+
+      &:active {
+        background-color: $mdlext-dark-button-fab-active-color-alt;
+      }
+
+      & .mdl-ripple {
+        background: $mdlext-dark-button-fab-ripple-color-alt;
+      }
+    }
+  }
+
+
+  // Icon buttons
+  .mdl-button--icon {
+    color: inherit;
+  }
+
+  // Colorized buttons
+
+  .mdl-button--primary.mdl-button--primary {
+    color: $mdlext-dark-button-primary-color-alt;
+
+    & .mdl-ripple {
+      background: $mdlext-dark-button-secondary-color-alt;
+    }
+    &.mdl-button--raised,
+    &.mdl-button--fab {
+      color: $mdlext-dark-button-secondary-color-alt;
+      background-color: $mdlext-dark-button-primary-color-alt;
+    }
+  }
+
+  .mdl-button--accent.mdl-button--accent {
+    color: $mdlext-dark-button-fab-color-alt;
+
+    & .mdl-ripple {
+      background: $mdlext-dark-button-fab-text-color-alt;
+    }
+    &.mdl-button--raised,
+    &.mdl-button--fab {
+      color: $mdlext-dark-button-fab-text-color-alt;
+      background-color: $mdlext-dark-button-fab-color-alt;
+    }
+  }
+
+  // Disabled buttons
+
+  .mdl-button {
+    // Bump up specificity by using [disabled] twice.
+    &[disabled][disabled],
+    &.mdl-button--disabled.mdl-button--disabled {
+      color: $mdlext-dark-button-secondary-color-disabled;
+      background-color: transparent;
+    }
+
+    &--fab {
+      // Bump up specificity by using [disabled] twice.
+      &[disabled][disabled],
+      &.mdl-button--disabled.mdl-button--disabled {
+        background-color: $mdlext-dark-button-primary-color-disabled;
+        color: $mdlext-dark-button-secondary-color-disabled;
+      }
+    }
+
+    &--raised {
+      // Bump up specificity by using [disabled] twice.
+      &[disabled][disabled],
+      &.mdl-button--disabled.mdl-button--disabled {
+        background-color: $mdlext-dark-button-primary-color-disabled;
+        color: $mdlext-dark-button-secondary-color-disabled;
+      }
+    }
+    &--colored {
+      // Bump up specificity by using [disabled] twice.
+      &[disabled][disabled],
+      &.mdl-button--disabled.mdl-button--disabled {
+        color: $mdlext-dark-button-secondary-color-disabled;
+      }
+    }
+  }
+}
+
+
+// mdl/src/slider/_slider.scss
+// ---------------------------
+.mdlext-dark-color-theme {
+
+  .mdl-slider {
+
+    &.is-upgraded {
+      background: transparent;
+      color: $mdlext-dark-range-color;
+
+      &::-webkit-slider-runnable-track {
+        background: transparent;
+      }
+
+      &::-moz-range-track {
+        background: transparent;
+      }
+
+      &::-ms-track {
+        background: none;
+        color: transparent;
+      }
+
+      /* stylelint-disable */
+      &::-ms-fill-lower {
+        background: linear-gradient(
+          to right,
+          transparent,
+          transparent 16px,
+          $mdlext-dark-range-color 16px,
+          $mdlext-dark-range-color 0
+        );
+      }
+
+      &::-ms-fill-upper {
+        background: linear-gradient(
+          to left,
+          transparent,
+          transparent 16px,
+          $mdlext-dark-range-bg-color 16px,
+          $mdlext-dark-range-bg-color 0);
+      }
+      /* stylelint-enable */
+
+      &::-webkit-slider-thumb {
+        background: $mdlext-dark-range-color;
+      }
+
+      &::-moz-range-thumb {
+        background: $mdlext-dark-range-color;
+      }
+
+      &:focus:not(:active)::-webkit-slider-thumb {
+        box-shadow: 0 0 0 10px $mdlext-dark-range-faded-color;
+      }
+
+      &:focus:not(:active)::-moz-range-thumb {
+        box-shadow: 0 0 0 10px $mdlext-dark-range-faded-color;
+      }
+
+      &:active::-webkit-slider-thumb {
+        background: $mdlext-dark-range-color;
+      }
+
+      &:active::-moz-range-thumb {
+        background: $mdlext-dark-range-color;
+      }
+
+      &::-ms-thumb {
+        background: $mdlext-dark-range-color;
+      }
+
+      /* stylelint-disable */
+      &:focus:not(:active)::-ms-thumb {
+        background: radial-gradient(circle closest-side,
+          $mdlext-dark-range-color 0%,
+          $mdlext-dark-range-color 37.5%,
+          $mdlext-dark-range-faded-color 37.5%,
+          $mdlext-dark-range-faded-color 100%);
+      }
+      /* stylelint-enable */
+
+      &:active::-ms-thumb {
+        background: $mdlext-dark-range-color;
+      }
+
+
+      /**************************** 0-value ****************************/
+
+      &.is-lowest-value::-webkit-slider-thumb {
+        border-color: $mdlext-dark-range-color;
+        background: transparent;
+      }
+
+      &.is-lowest-value::-moz-range-thumb {
+        border-color: $mdlext-dark-range-bg-color;
+        background: transparent;
+      }
+
+      &.is-lowest-value:focus:not(:active)::-webkit-slider-thumb {
+        box-shadow: 0 0 0 10px $mdlext-dark-range-bg-focus-color;
+        background: $mdlext-dark-range-bg-focus-color;
+      }
+
+      &.is-lowest-value:focus:not(:active)::-moz-range-thumb {
+        box-shadow: 0 0 0 10px $mdlext-dark-range-bg-focus-color;
+        background: $mdlext-dark-range-bg-focus-color;
+      }
+
+      &.is-lowest-value:active::-webkit-slider-thumb {
+        border-color: $mdlext-dark-range-bg-color;
+      }
+
+      &.is-lowest-value:active::-moz-range-thumb {
+        border-color: $mdlext-dark-range-bg-color;
+      }
+
+      /* stylelint-disable */
+      &.is-lowest-value::-ms-thumb {
+        background: radial-gradient(circle closest-side,
+          transparent 0%,
+          transparent 66.67%,
+          $mdlext-dark-range-bg-color 66.67%,
+          $mdlext-dark-range-bg-color 100%);
+      }
+
+      &.is-lowest-value:focus:not(:active)::-ms-thumb {
+        background: radial-gradient(circle closest-side,
+          $mdlext-dark-range-bg-focus-color 0%,
+          $mdlext-dark-range-bg-focus-color 25%,
+          $mdlext-dark-range-bg-color 25%,
+          $mdlext-dark-range-bg-color 37.5%,
+          $mdlext-dark-range-bg-focus-color 37.5%,
+          $mdlext-dark-range-bg-focus-color 100%);
+      }
+
+      &.is-lowest-value:active::-ms-thumb {
+        background: radial-gradient(circle closest-side,
+          transparent 0%,
+          transparent 77.78%,
+          $mdlext-dark-range-bg-color 77.78%,
+          $mdlext-dark-range-bg-color 100%);
+      }
+      /* stylelint-enable */
+
+      &.is-lowest-value::-ms-fill-lower {
+        background: transparent;
+      }
+
+      /**************************** Disabled ****************************/
+
+      &:disabled:focus::-webkit-slider-thumb,
+      &:disabled:active::-webkit-slider-thumb,
+      &:disabled::-webkit-slider-thumb {
+        background: $mdlext-dark-range-bg-color;
+      }
+
+      &:disabled:focus::-moz-range-thumb,
+      &:disabled:active::-moz-range-thumb,
+      &:disabled::-moz-range-thumb {
+        background: $mdlext-dark-range-bg-color;
+      }
+
+      &:disabled + .mdl-slider__background-flex > .mdl-slider__background-lower {
+        background-color: $mdlext-dark-range-bg-color;
+      }
+
+      &.is-lowest-value:disabled:focus::-webkit-slider-thumb,
+      &.is-lowest-value:disabled:active::-webkit-slider-thumb,
+      &.is-lowest-value:disabled::-webkit-slider-thumb {
+        border-color: $mdlext-dark-range-bg-color;
+        background: transparent;
+      }
+
+      &.is-lowest-value:disabled:focus::-moz-range-thumb,
+      &.is-lowest-value:disabled:active::-moz-range-thumb,
+      &.is-lowest-value:disabled::-moz-range-thumb {
+        border-color: $mdlext-dark-range-bg-color;
+        background: transparent;
+      }
+
+      &:disabled:focus::-ms-thumb,
+      &:disabled:active::-ms-thumb,
+      &:disabled::-ms-thumb {
+        background: $mdlext-dark-range-bg-color;
+      }
+
+      /* stylelint-disable */
+      &.is-lowest-value:disabled:focus::-ms-thumb,
+      &.is-lowest-value:disabled:active::-ms-thumb,
+      &.is-lowest-value:disabled::-ms-thumb {
+        background: radial-gradient(circle closest-side,
+          transparent 0%,
+          transparent 50%,
+          $mdlext-dark-range-bg-color 50%,
+          $mdlext-dark-range-bg-color 100%);
+      }
+
+      &:disabled::-ms-fill-lower {
+        background: linear-gradient(to right,
+          transparent,
+          transparent 25px,
+          $mdlext-dark-range-bg-color 25px,
+          $mdlext-dark-range-bg-color 0);
+      }
+      /* stylelint-enable */
+
+    }
+  }
+
+  .mdl-slider__background-flex {
+    background: transparent;
+  }
+
+  .mdl-slider__background-lower {
+    background: $mdlext-dark-range-color;
+  }
+
+  // This one styles the upper part of the slider track.
+  .mdl-slider__background-upper {
+    background: $mdlext-dark-range-bg-color;
+  }
+}
+
+
+// mdl/src/textfield/_textfield.scss
+// -----------------------------------
+.mdlext-dark-color-theme {
+
+  .mdl-textfield__input {
+    border-bottom-color: $mdlext-dark-input-text-bottom-border-color;
+  }
+  .mdl-textfield.is-invalid .mdl-textfield__input {
+    border-color: $mdlext-dark-input-text-error-color;
+  }
+  fieldset[disabled] .mdl-textfield .mdl-textfield__input,
+  .mdl-textfield.is-disabled .mdl-textfield__input {
+    background-color: transparent;
+    border-bottom-color: $mdlext-dark-input-text-disabled-color;
+    color: $mdlext-dark-input-text-disabled-text-color;
+  }
+  .mdl-textfield__label {
+    color: $mdlext-dark-input-text-label-color;
+  }
+  .mdl-textfield__label::after {
+    background-color: $mdlext-dark-input-text-highlight-color;
+  }
+  fieldset[disabled] .mdl-textfield .mdl-textfield__label,
+  .mdl-textfield.is-disabled.is-disabled .mdl-textfield__label {
+    color: $mdlext-dark-input-text-disabled-text-color;
+  }
+  .mdl-textfield--floating-label.is-focused .mdl-textfield__label,
+  .mdl-textfield--floating-label.is-dirty .mdl-textfield__label,
+  .mdl-textfield--floating-label.has-placeholder .mdl-textfield__label {
+    color: $mdlext-dark-input-text-highlight-color;
+  }
+  .mdl-textfield--floating-label.is-invalid .mdl-textfield__label {
+    color: $mdlext-dark-input-text-error-color;
+  }
+  .mdl-textfield.is-invalid .mdl-textfield__label::after {
+    background-color: $mdlext-dark-input-text-error-color;
+  }
+  .mdl-textfield__error {
+    color: $mdlext-dark-input-text-error-color;
+  }
+}
+
+
+// mdl/src/checkbox/_checkbox.scss
+// -----------------------------------
+.mdlext-dark-color-theme {
+
+  .mdl-checkbox__box-outline {
+    border-color: $mdlext-dark-checkbox-off-color;
+  }
+  .mdl-checkbox.is-checked .mdl-checkbox__box-outline {
+    border-color: $mdlext-dark-checkbox-color;
+  }
+  fieldset[disabled] .mdl-checkbox .mdl-checkbox__box-outline,
+  .mdl-checkbox.is-disabled .mdl-checkbox__box-outline {
+    border-color: $mdlext-dark-checkbox-disabled-color;
+  }
+
+  .mdl-checkbox__focus-helper {
+    background-color: transparent;
+  }
+  .mdl-checkbox.is-focused.is-checked .mdl-checkbox__focus-helper {
+    box-shadow: 0 0 0 ($checkbox-button-size / 2) $mdlext-dark-checkbox-focus-color;
+    background-color: $mdlext-dark-checkbox-focus-color;
+  }
+
+  .mdl-checkbox__tick-outline {
+    background: transparent;
+  }
+  .mdl-checkbox.is-checked .mdl-checkbox__tick-outline {
+    background-color: $mdlext-dark-checkbox-color;
+  }
+  fieldset[disabled] .mdl-checkbox.is-checked .mdl-checkbox__tick-outline,
+  .mdl-checkbox.is-checked.is-disabled .mdl-checkbox__tick-outline {
+    background-color: $mdlext-dark-checkbox-disabled-color;
+  }
+
+  fieldset[disabled] .mdl-checkbox .mdl-checkbox__label,
+  .mdl-checkbox.is-disabled .mdl-checkbox__label {
+    color: $mdlext-dark-checkbox-disabled-color;
+  }
+
+  .mdl-checkbox__ripple-container .mdl-ripple {
+    background: $mdlext-dark-checkbox-color;
+  }
+  fieldset[disabled] .mdl-checkbox .mdl-checkbox__ripple-container .mdl-ripple,
+  .mdl-checkbox.is-disabled .mdl-checkbox__ripple-container .mdl-ripple {
+    background: transparent;
+  }
+
+}
+
+// mdl/src/radio/_radio.scss
+// -----------------------------------
+.mdlext-dark-color-theme {
+  .mdl-radio__outer-circle {
+    border-color: $mdlext-dark-radio-off-color;
+  }
+  .mdl-radio.is-checked .mdl-radio__outer-circle {
+    border-color: $mdlext-dark-radio-color;
+  }
+  .mdl-radio__outer-circle fieldset[disabled] .mdl-radio,
+  .mdl-radio.is-disabled .mdl-radio__outer-circle {
+    border-color: $mdlext-dark-radio-disabled-color;
+  }
+
+  .mdl-radio__inner-circle {
+    background: $mdlext-dark-radio-color;
+  }
+  fieldset[disabled] .mdl-radio .mdl-radio__inner-circle,
+  .mdl-radio.is-disabled .mdl-radio__inner-circle {
+    background: $mdlext-dark-radio-disabled-color;
+  }
+
+  fieldset[disabled] .mdl-radio .mdl-radio__label,
+  .mdl-radio.is-disabled .mdl-radio__label {
+    color: $mdlext-dark-radio-disabled-color;
+  }
+
+  .mdl-radio__ripple-container .mdl-ripple {
+    background: $mdlext-dark-radio-color;
+  }
+  fieldset[disabled] .mdl-radio .mdl-radio__ripple-container .mdl-ripple,
+  .mdl-radio.is-disabled .mdl-radio__ripple-container .mdl-ripple {
+    background: transparent;
+  }
+}
+
+// mdl/src/icon-togglr/_icon-toggle.scss
+// ---------------------------------------
+.mdlext-dark-color-theme {
+  .mdl-icon-toggle__label {
+    color: $mdlext-dark-icon-toggle-color;
+  }
+  .mdl-icon-toggle.is-checked .mdl-icon-toggle__label {
+    color: $mdlext-dark-icon-toggle-checked-color;
+  }
+  .mdl-icon-toggle.is-disabled .mdl-icon-toggle__label {
+    color: $mdlext-dark-icon-toggle-disabled-color;
+  }
+  .mdl-icon-toggle.is-focused .mdl-icon-toggle__label {
+    background-color: $mdlext-dark-icon-toggle-focus-color;
+  }
+  .mdl-icon-toggle.is-focused.is-checked .mdl-icon-toggle__label {
+    background-color: $mdlext-dark-icon-toggle-checked-focus-color;
+  }
+  .mdl-icon-toggle__ripple-container .mdl-ripple {
+    background: $mdlext-dark-icon-toggle-color;
+  }
+  .mdl-icon-toggle.is-disabled .mdl-icon-toggle__ripple-container .mdl-ripple {
+    background: transparent;
+  }
+}
+
+
+// mdl/src/switch/_switch.scss
+// -----------------------------------
+.mdlext-dark-color-theme {
+
+  .mdl-switch__track {
+    background: $mdlext-dark-switch-off-track-color;
+  }
+  .mdl-switch.is-checked .mdl-switch__track {
+    background: $mdlext-dark-switch-track-color;
+  }
+  .mdl-switch__track fieldset[disabled] .mdl-switch,
+  .mdl-switch.is-disabled .mdl-switch__track {
+    background: $mdlext-dark-switch-disabled-track-color;
+  }
+
+  .mdl-switch__thumb {
+    background: $mdlext-dark-switch-off-thumb-color;
+  }
+  .mdl-switch.is-checked .mdl-switch__thumb {
+    background: $mdlext-dark-switch-thumb-color;
+  }
+  .mdl-switch__thumb fieldset[disabled] .mdl-switch,
+  .mdl-switch.is-disabled .mdl-switch__thumb {
+    background: $mdlext-dark-switch-disabled-thumb-color;
+  }
+
+  .mdl-switch__focus-helper {
+    background-color: transparent;
+  }
+  .mdl-switch.is-focused .mdl-switch__focus-helper {
+    background-color: rgba(0, 0, 0, 0.1);
+  }
+  .mdl-switch.is-focused.is-checked .mdl-switch__focus-helper {
+    box-shadow: 0 0 0 (($switch-ripple-size - $switch-helper-size) / 2) $mdlext-dark-switch-faded-color;
+    background-color: $mdlext-dark-switch-faded-color;
+  }
+
+  .mdl-switch__label fieldset[disabled] .mdl-switch,
+  .mdl-switch.is-disabled .mdl-switch__label {
+    color: $mdlext-dark-switch-disabled-thumb-color;
+  }
+
+  .mdl-switch__ripple-container .mdl-ripple {
+    background: $mdlext-dark-switch-color;
+  }
+  fieldset[disabled] .mdl-switch .mdl-switch__ripple-container .mdl-ripple,
+  .mdl-switch.is-disabled .mdl-switch__ripple-container .mdl-ripple {
+    background: transparent;
+  }
+
+}
+
+
+// mdl/src/data-table/_data-table.scss
+// -----------------------------------
+.mdlext-dark-color-theme {
+
+  .mdl-data-table {
+    border-color: $mdlext-dark-data-table-divider-color;
+    background-color: $mdlext-dark-data-table-background-color;
+
+    tbody {
+      tr {
+        &.is-selected {
+          background-color: $mdlext-dark-data-table-selection-color;
+        }
+
+        &:hover {
+          background-color: $mdlext-dark-data-table-hover-color;
+        }
+      }
+    }
+
+    th {
+      color: $mdlext-dark-data-table-header-color;
+
+      &.mdl-data-table__header--sorted-ascending,
+      &.mdl-data-table__header--sorted-descending {
+        color: $mdlext-dark-data-table-header-sorted-color;
+
+        &:hover {
+          &::before {
+            color: $mdlext-dark-data-table-header-sorted-icon-hover-color;
+          }
+        }
+      }
+    }
+  }
+}
+
+// mdl/src/menu/_menu.scss
+// -----------------------------------
+.mdlext-dark-color-theme {
+
+  .mdl-menu__outline {
+    background: $mdlext-dark-default-dropdown-bg-color;
+  }
+
+  .mdl-menu__item {
+    color: $mdlext-dark-default-item-text-color;
+    background-color: transparent;
+    outline-color: $mdlext-dark-default-item-outline-color;
+
+    &--full-bleed-divider {
+      border-bottom-color: $mdlext-dark-default-item-divider-color;
+    }
+
+    &[disabled],
+    &[data-mdl-disabled] {
+      color: $mdlext-dark-disabled-item-text-color;
+      background-color: transparent;
+
+      &:hover {
+        background-color: transparent;
+      }
+
+      &:focus {
+        background-color: transparent;
+      }
+
+      & .mdl-ripple {
+        background: transparent;
+      }
+    }
+
+    &:hover {
+      background-color: $mdlext-dark-default-item-hover-bg-color;
+    }
+
+    &:focus {
+      background-color: $mdlext-dark-default-item-focus-bg-color;
+    }
+
+    &:active {
+      background-color: $mdlext-dark-default-item-active-bg-color;
+    }
+  }
+}
+
+// mdl/src/card/_card.scss
+// ----------------------------------------
+.mdlext-dark-color-theme {
+  .mdl-card {
+    background: $mdlext-dark-card-background-color;
+  }
+
+  .mdl-card__media {
+    background-color: $mdlext-dark-card-image-placeholder-color;
+  }
+
+  .mdl-card__title {
+    color: $mdlext-dark-card-text-color;
+
+    &.mdl-card--border {
+      border-bottom-color: $mdlext-dark-card-border-color;
+    }
+  }
+
+  .mdl-card__title-text {
+    color: inherit;
+  }
+
+  .mdl-card__subtitle-text {
+    color: $mdlext-dark-card-subtitle-color;
+  }
+
+  .mdl-card__supporting-text {
+    color: $mdlext-dark-card-supporting-text-text-color;
+  }
+
+  .mdl-card__actions {
+    background-color: rgba(255, 255, 255, 0);
+
+    &.mdl-card--border {
+      border-top-color: $mdlext-dark-card-border-color;
+    }
+  }
+}
+
+
+// mdlext/src/selectfield/_selectfield.scss
+// ----------------------------------------
+.mdlext-dark-color-theme {
+
+  .mdlext-selectfield.is-disabled::after {
+    color: $mdlext-dark-input-text-disabled-color;
+    @include mdlext-arrow(bottom, $mdlext-selectfield-arrow-width, $mdlext-selectfield-arrow-length, $mdlext-dark-input-text-disabled-color);
+  }
+
+  .mdlext-selectfield__select {
+    border-bottom-color: $mdlext-dark-input-text-bottom-border-color;
+    color: inherit;
+
+    option {
+      background-color: $mdlext-dark-content-background-color;
+      color: $mdlext-dark-text-color-primary;
+    }
+  }
+  .mdlext-selectfield.is-invalid .mdlext-selectfield__select {
+    border-color: $mdlext-dark-input-text-error-color;
+  }
+  fieldset[disabled] .mdlext-selectfield .mdlext-selectfield__select,
+  .mdlext-selectfield.is-disabled .mdlext-selectfield__select {
+    background-color: transparent;
+    border-bottom-color: $mdlext-dark-input-text-disabled-color;
+    color: $mdlext-dark-input-text-disabled-text-color;
+  }
+
+  .mdlext-selectfield__label {
+    color: $mdlext-dark-input-text-label-color;
+  }
+  fieldset[disabled] .mdlext-selectfield .mdlext-selectfield__label,
+  .mdlext-selectfield.is-disabled.is-disabled .mdlext-selectfield__label {
+    color: $mdlext-dark-input-text-disabled-text-color;
+  }
+  .mdlext-selectfield--floating-label.is-focused .mdlext-selectfield__label,
+  .mdlext-selectfield--floating-label.is-dirty .mdlext-selectfield__label,
+  .mdlext-selectfield--floating-label.is-dirty.is-dirty .mdlext-selectfield__label,
+  .mdlext-selectfield--floating-label.has-placeholder .mdlext-selectfield__label {
+    color: $mdlext-dark-input-text-highlight-color;
+  }
+  .mdlext-selectfield--floating-label.is-invalid .mdlext-selectfield__label {
+    color: $mdlext-dark-input-text-error-color;
+  }
+  .mdlext-selectfield__label::after {
+    background-color: $mdlext-dark-input-text-highlight-color;
+  }
+  .mdlext-selectfield.is-invalid .mdlext-selectfield__label::after {
+    background-color: $mdlext-dark-input-text-error-color;
+  }
+
+  .mdlext-selectfield__error {
+    color: $mdlext-dark-input-text-error-color;
+  }
+}
+
+
+// mdlext/src/menu-button/_menu-button.scss
+// ----------------------------------------
+.mdlext-menu.mdlext-dark-color-theme {
+  background: $mdlext-dark-default-dropdown-bg-color;
+}
+
+.mdlext-dark-color-theme {
+
+  .mdlext-menu {
+    background: $mdlext-dark-default-dropdown-bg-color;
+
+    &__item {
+      color: $mdlext-dark-default-item-text-color;
+      background-color: $mdlext-dark-default-dropdown-bg-color;
+
+      &:active,
+      &[aria-selected='true'] {
+        background-color: $mdlext-dark-default-item-active-bg-color;
+      }
+      &:hover:not([disabled]) {
+        background-color: $mdlext-dark-default-item-hover-bg-color;
+      }
+      &:focus {
+        outline-color: $mdlext-dark-default-item-outline-color;
+        background-color: $mdlext-dark-default-item-focus-bg-color;
+      }
+      &[disabled] {
+        color: $mdlext-dark-disabled-item-text-color;
+
+        > * {
+          color: $mdlext-dark-disabled-item-text-color;
+        }
+      }
+    }
+    &__item-separator {
+      border-bottom: 1px solid $mdlext-dark-default-item-divider-color;
+    }
+  }
+}
+
+
+// mdlext/src/bordered-fields/_bordered-fields.scss
+// -------------------------------------------------
+.mdlext-dark-color-theme {
+
+  .mdlext-bordered-fields {
+
+    .mdl-textfield,
+    .mdlext-selectfield {
+
+      .mdl-textfield__input,
+      .mdlext-selectfield__select {
+        background-color: $mdlext-dark-bordered-field-background-color;
+        border-color: $mdlext-dark-bordered-field-border-color;
+        color: $mdlext-dark-bordered-field-input-text-color;
+
+        &:disabled {
+          color: $mdlext-dark-bordered-field-input-text-disabled-text-color;
+          background-color: $mdlext-dark-bordered-field-disabled-background-color;
+          border-color: $mdlext-dark-bordered-field-disabled-border-color;
+        }
+        &:focus {
+          background-color: $mdlext-dark-bordered-field-focus-background-color;
+          border-color: $mdlext-dark-bordered-field-focus-border-color;
+        }
+      }
+      &.is-invalid {
+        .mdl-textfield__input,
+        .mdlext-selectfield__select {
+          color: $mdlext-dark-bordered-field-input-text-error-color;
+          border-color: $mdlext-dark-bordered-field-error-border-color;
+          background-color: $mdlext-dark-bordered-field-error-background-color;
+
+          &:focus {
+            border-color: $mdlext-dark-bordered-field-error-focus-border-color;
+            background-color: $mdlext-dark-bordered-field-error-focus-background-color;
+          }
+        }
+      }
+    }
+
+    fieldset[disabled] .mdlext-selectfield::after,
+    .mdlext-selectfield.is-disabled::after {
+      color: $mdlext-dark-bordered-field-input-text-disabled-text-color;
+      @include mdlext-arrow(bottom, $mdlext-selectfield-arrow-width, $mdlext-selectfield-arrow-length, $mdlext-dark-bordered-field-input-text-disabled-text-color);
+    }
+
+    fieldset[disabled] .mdl-textfield .mdl-textfield__input,
+    fieldset[disabled] .mdlext-selectfield .mdlext-selectfield__select {
+      color: $mdlext-dark-bordered-field-input-text-disabled-text-color;
+      background-color: $mdlext-dark-bordered-field-disabled-background-color;
+      border-color: $mdlext-dark-bordered-field-disabled-border-color;
+    }
+
+    .mdl-textfield,
+    .mdlext-selectfield {
+
+      .mdl-textfield__label,
+      .mdlext-selectfield__label {
+        color: $mdlext-dark-bordered-field-input-text-label-color;
+      }
+      &.mdl-textfield--floating-label.is-focused.is-focused,
+      &.mdl-textfield--floating-label.is-dirty.is-dirty,
+      &.mdl-textfield--floating-label.has-placeholder,
+      &.mdlext-selectfield--floating-label.is-focused.is-focused,
+      &.mdlext-selectfield--floating-label.is-dirty.is-dirty,
+      &.mdlext-selectfield--floating-label.has-placeholder {
+
+        .mdl-textfield__label,
+        .mdlext-selectfield__label {
+          color: $mdlext-dark-bordered-field-input-text-label-focus-color;
+        }
+      }
+      &.mdl-textfield--floating-label.is-disabled.is-disabled,
+      &.mdlext-selectfield--floating-label.is-disabled.is-disabled {
+
+        .mdl-textfield__label,
+        .mdlext-selectfield__label {
+          color: $mdlext-dark-bordered-field-input-text-label-disabled-color;
+        }
+      }
+      &.mdl-textfield--floating-label.is-invalid.is-invalid,
+      &.mdlext-selectfield--floating-label.is-invalid.is-invalid {
+
+        .mdl-textfield__label,
+        .mdlext-selectfield__label {
+          color: $mdlext-dark-bordered-field-input-text-label-error-color;
+        }
+      }
+    }
+
+    fieldset[disabled] .mdl-textfield .mdl-textfield__label,
+    fieldset[disabled] .mdl-selectfield .mdl-selectfield__label {
+      color: $mdlext-dark-bordered-field-input-text-label-disabled-color;
+    }
+
+    // Icon(s) and/or button(s) inside textfield
+    .mdl-textfield,
+    .mdlext-selectfield {
+      &.is-disabled i,
+      &.is-disabled .mdl-button {
+        color: $mdlext-dark-bordered-field-disabled-border-color;
+      }
+    }
+    fieldset[disabled] .mdl-textfield,
+    fieldset[disabled] .mdlext-selectfield {
+      i,
+      .mdl-button {
+        color: $mdlext-dark-bordered-field-disabled-border-color;
+      }
+    }
+  }
+
+}
+
+
+// mdlext/src/accordion/_accordion.scss
+// ----------------------------------------
+.mdlext-dark-color-theme {
+
+  .mdlext-accordion {
+
+    &__tab {
+      color: $mdlext-dark-accordion-header-secondary-color;
+      background-color: $mdlext-dark-accordion-header-background-color;
+
+      &:focus {
+        outline-color: $mdlext-dark-accordion-header-focus-outline-color;
+      }
+      &[aria-expanded='true'] {
+        background-color: $mdlext-dark-accordion-header-background-open-color;
+      }
+      &[aria-selected='true'] {
+        background-color: $mdlext-dark-accordion-header-background-active-color;
+      }
+      &[disabled] {
+        background-color: $mdlext-dark-accordion-header-disabled-color;
+        color: $mdlext-dark-accordion-header-secondary-color-disabled;
+        pointer-events: none;
+
+        > * {
+          color: $mdlext-dark-accordion-header-secondary-color-disabled;
+        }
+      }
+      &:hover:not([disabled]) {
+        background-color: $mdlext-dark-accordion-header-background-hover-color;
+      }
+      &--ripple {
+        &[aria-selected='true']::before {
+          background: $mdlext-dark-accordion-ripple-color;
+        }
+      }
+    }
+
+    &__tabpanel {
+      color: $mdlext-dark-accordion-content-color;
+      background-color: $mdlext-dark-accordion-content-background-color;
+    }
+  }
+
+  // Vertical layout
+  .mdlext-accordion {
+
+    &--vertical {
+
+      .mdlext-accordion__tab {
+        border-top: 1px solid $mdlext-dark-accordion-header-border-color;
+
+        &[aria-selected='true']::after {
+          background-color: $mdlext-dark-accordion-header-highlight-color;
+        }
+      }
+      .mdlext-accordion__tabpanel {
+        border-top: 1px solid $mdlext-dark-accordion-header-border-color;
+      }
+    }
+  }
+
+  // Horizontal layout
+  .mdlext-accordion {
+
+    &--horizontal {
+
+      .mdlext-accordion__tab {
+        border-left: 1px solid $mdlext-dark-accordion-header-border-color;
+
+        &[aria-selected='true']::after {
+          background-color: $mdlext-dark-accordion-header-highlight-color;
+        }
+      }
+      .mdlext-accordion__tabpanel {
+        border-left: 1px solid $mdlext-dark-accordion-header-border-color;
+      }
+    }
+  }
+
+  .mdlext-accordion {
+
+    &__panel:first-child > &__tab {
+      // Use container to set outer borders
+      border-top-color: transparent;
+      border-left-color: transparent;
+    }
+  }
+
+  // Making accordion appear disabled.
+  // Note: does not prevent tabbing into a disabled accordion
+  .mdlext-accordion[disabled] {
+    .mdlext-accordion__tab {
+      background-color: $mdlext-dark-accordion-header-disabled-color;
+      color: $mdlext-dark-accordion-header-secondary-color-disabled;
+
+      > * {
+        color: $mdlext-dark-accordion-header-secondary-color-disabled;
+      }
+    }
+    .mdlext-accordion__tabpanel {
+      opacity: 0.8;
+      filter: blur(1px) grayscale(80%);
+    }
+  }
+}
diff --git a/node_modules/mdl-ext/src/color-themes/_light-color-theme.scss b/node_modules/mdl-ext/src/color-themes/_light-color-theme.scss
new file mode 100644
index 0000000..5393738
--- /dev/null
+++ b/node_modules/mdl-ext/src/color-themes/_light-color-theme.scss
@@ -0,0 +1,1130 @@
+@import "color-themes";
+
+.mdlext-light-color-theme {
+  background-color: $mdlext-light-content-background-color;
+  color: $mdlext-light-text-color-primary;
+
+  a {
+    outline-color: inherit;
+  }
+}
+
+// mdl/src/palette/_palette.scss
+// -----------------------------
+.mdlext-light-color-theme {
+
+  .mdl-color--primary {
+    background-color: $mdlext-light-color-primary !important;
+  }
+
+  .mdl-color--primary-contrast {
+    background-color: $mdlext-light-color-primary-contrast !important;
+  }
+
+  .mdl-color--primary-dark {
+    background-color: $mdlext-light-color-primary-dark !important;
+  }
+
+  .mdl-color--accent {
+    background-color: $mdlext-light-color-accent !important;
+  }
+
+  .mdl-color--accent-contrast {
+    background-color: $mdlext-light-color-accent-contrast !important;
+  }
+
+  .mdl-color-text--primary {
+    color: $mdlext-light-color-primary !important;
+  }
+
+  .mdl-color-text--primary-contrast {
+    color: $mdlext-light-color-primary-contrast !important;
+  }
+
+  .mdl-color-text--primary-dark {
+    color: $mdlext-light-color-primary-dark !important;
+  }
+
+  .mdl-color-text--accent {
+    color: $mdlext-light-color-accent !important;
+  }
+
+  .mdl-color-text--accent-contrast {
+    color: $mdlext-light-color-accent-contrast !important;
+  }
+
+}
+
+// mdl/src/typography/_typography.scss
+// -----------------------------------
+.mdlext-light-color-theme {
+  a {
+    color: $mdlext-light-text-link-color;
+  }
+}
+
+
+// mdl/src/badge/_badge.scss
+// ---------------------------
+.mdlext-light-color-theme {
+  .mdl-badge {
+
+    &[data-badge]::after {
+      background: $mdlext-light-badge-background;
+      color: $mdlext-light-badge-color;
+    }
+
+    &.mdl-badge--no-background {
+      &[data-badge]::after {
+        color: $mdlext-light-badge-color-inverse;
+        background: $mdlext-light-badge-background-inverse;
+      }
+    }
+  }
+}
+
+
+// mdl/src/button/_button.scss
+// ---------------------------
+.mdlext-light-color-theme {
+
+  .mdl-button {
+    background: transparent;
+    color: $mdlext-light-button-secondary-color;
+
+    &:hover {
+      background-color: $mdlext-light-button-hover-color;
+    }
+
+    &:focus:not(:active) {
+      background-color: $mdlext-light-button-focus-color;
+    }
+
+    &:active {
+      background-color: $mdlext-light-button-active-color;
+    }
+
+    &.mdl-button--colored {
+      color: $mdlext-light-button-primary-color-alt;
+
+      &:focus:not(:active) {
+        background-color: $mdlext-light-button-focus-color-alt;
+      }
+    }
+  }
+
+  // Raised buttons
+  .mdl-button--raised {
+    background: $mdlext-light-button-primary-color;
+
+    &:active {
+      background-color: $mdlext-light-button-active-color;
+    }
+
+    &:focus:not(:active) {
+      background-color: $mdlext-light-button-active-color;
+    }
+
+    &.mdl-button--colored {
+      background: $mdlext-light-button-primary-color-alt;
+      color: $mdlext-light-button-secondary-color-alt;
+
+      &:hover {
+        background-color: $mdlext-light-button-hover-color-alt;
+      }
+
+      &:active {
+        background-color: $mdlext-light-button-active-color-alt;
+      }
+
+      &:focus:not(:active) {
+        background-color: $mdlext-light-button-active-color-alt;
+      }
+
+      & .mdl-ripple {
+        background: $mdlext-light-button-ripple-color-alt;
+      }
+    }
+  }
+
+
+  // FABs
+  .mdl-button--fab {
+    background: $mdlext-light-button-primary-color;
+
+    &:active {
+      background-color: $mdlext-light-button-active-color;
+    }
+
+    &:focus:not(:active) {
+      background-color: $mdlext-light-button-active-color;
+    }
+
+    &.mdl-button--colored {
+      background: $mdlext-light-button-fab-color-alt;
+      color: $mdlext-light-button-fab-text-color-alt;
+
+      &:hover {
+        background-color: $mdlext-light-button-fab-hover-color-alt;
+      }
+
+      &:focus:not(:active) {
+        background-color: $mdlext-light-button-fab-active-color-alt;
+      }
+
+      &:active {
+        background-color: $mdlext-light-button-fab-active-color-alt;
+      }
+
+      & .mdl-ripple {
+        background: $mdlext-light-button-fab-ripple-color-alt;
+      }
+    }
+  }
+
+
+  // Icon buttons
+  .mdl-button--icon {
+    color: inherit;
+  }
+
+  // Colorized buttons
+
+  .mdl-button--primary.mdl-button--primary {
+    color: $mdlext-light-button-primary-color-alt;
+
+    & .mdl-ripple {
+      background: $mdlext-light-button-secondary-color-alt;
+    }
+    &.mdl-button--raised,
+    &.mdl-button--fab {
+      color: $mdlext-light-button-secondary-color-alt;
+      background-color: $mdlext-light-button-primary-color-alt;
+    }
+  }
+
+  .mdl-button--accent.mdl-button--accent {
+    color: $mdlext-light-button-fab-color-alt;
+
+    & .mdl-ripple {
+      background: $mdlext-light-button-fab-text-color-alt;
+    }
+    &.mdl-button--raised,
+    &.mdl-button--fab {
+      color: $mdlext-light-button-fab-text-color-alt;
+      background-color: $mdlext-light-button-fab-color-alt;
+    }
+  }
+
+  // Disabled buttons
+
+  .mdl-button {
+    // Bump up specificity by using [disabled] twice.
+    &[disabled][disabled],
+    &.mdl-button--disabled.mdl-button--disabled {
+      color: $mdlext-light-button-secondary-color-disabled;
+      background-color: transparent;
+    }
+
+    &--fab {
+      // Bump up specificity by using [disabled] twice.
+      &[disabled][disabled],
+      &.mdl-button--disabled.mdl-button--disabled {
+        background-color: $mdlext-light-button-primary-color-disabled;
+        color: $mdlext-light-button-secondary-color-disabled;
+      }
+    }
+
+    &--raised {
+      // Bump up specificity by using [disabled] twice.
+      &[disabled][disabled],
+      &.mdl-button--disabled.mdl-button--disabled {
+        background-color: $mdlext-light-button-primary-color-disabled;
+        color: $mdlext-light-button-secondary-color-disabled;
+      }
+    }
+    &--colored {
+      // Bump up specificity by using [disabled] twice.
+      &[disabled][disabled],
+      &.mdl-button--disabled.mdl-button--disabled {
+        color: $mdlext-light-button-secondary-color-disabled;
+      }
+    }
+  }
+}
+
+// mdl/src/slider/_slider.scss
+// ---------------------------
+.mdlext-light-color-theme {
+  .mdl-slider {
+
+    &.is-upgraded {
+      background: transparent;
+      color: $mdlext-light-range-color;
+
+      &::-webkit-slider-runnable-track {
+        background: transparent;
+      }
+
+      &::-moz-range-track {
+        background: transparent;
+      }
+
+      &::-ms-track {
+        background: none;
+        color: transparent;
+      }
+
+      /* stylelint-disable */
+      &::-ms-fill-lower {
+        background: linear-gradient(to right,
+          transparent,
+          transparent 16px,
+          $mdlext-light-range-color 16px,
+          $mdlext-light-range-color 0);
+      }
+
+      &::-ms-fill-upper {
+        background: linear-gradient(to left,
+          transparent,
+          transparent 16px,
+          $mdlext-light-range-bg-color 16px,
+          $mdlext-light-range-bg-color 0);
+      }
+      /* stylelint-enable */
+
+
+      /**************************** Thumbs ****************************/
+      &::-webkit-slider-thumb {
+        background: $mdlext-light-range-color;
+      }
+
+      &::-moz-range-thumb {
+        background: $mdlext-light-range-color;
+      }
+
+      &:focus:not(:active)::-webkit-slider-thumb {
+        box-shadow: 0 0 0 10px $mdlext-light-range-faded-color;
+      }
+
+      &:focus:not(:active)::-moz-range-thumb {
+        box-shadow: 0 0 0 10px $mdlext-light-range-faded-color;
+      }
+
+      &:active::-webkit-slider-thumb {
+        background: $mdlext-light-range-color;
+      }
+
+      &:active::-moz-range-thumb {
+        background: $mdlext-light-range-color;
+      }
+
+      &::-ms-thumb {
+        background: $mdlext-light-range-color;
+      }
+
+      /* stylelint-disable */
+      &:focus:not(:active)::-ms-thumb {
+        background: radial-gradient(circle closest-side,
+          $mdlext-light-range-color 0%,
+          $mdlext-light-range-color 37.5%,
+          $mdlext-light-range-faded-color 37.5%,
+          $mdlext-light-range-faded-color 100%);
+      }
+      /* stylelint-enable */
+
+      &:active::-ms-thumb {
+        background: $mdlext-light-range-color;
+      }
+
+
+      /**************************** 0-value ****************************/
+
+      &.is-lowest-value::-webkit-slider-thumb {
+        border-color: $mdlext-light-range-color;
+        background: transparent;
+      }
+
+      &.is-lowest-value::-moz-range-thumb {
+        border-color: $mdlext-light-range-bg-color;
+        background: transparent;
+      }
+
+      &.is-lowest-value:focus:not(:active)::-webkit-slider-thumb {
+        box-shadow: 0 0 0 10px $mdlext-light-range-bg-focus-color;
+        background: $mdlext-light-range-bg-focus-color;
+      }
+
+      &.is-lowest-value:focus:not(:active)::-moz-range-thumb {
+        box-shadow: 0 0 0 10px $mdlext-light-range-bg-focus-color;
+        background: $mdlext-light-range-bg-focus-color;
+      }
+
+      &.is-lowest-value:active::-webkit-slider-thumb {
+        border-color: $mdlext-light-range-bg-color;
+      }
+
+      &.is-lowest-value:active::-moz-range-thumb {
+        border-color: $mdlext-light-range-bg-color;
+      }
+
+      /* stylelint-disable */
+      &.is-lowest-value::-ms-thumb {
+        background: radial-gradient(circle closest-side,
+          transparent 0%,
+          transparent 66.67%,
+          $mdlext-light-range-bg-color 66.67%,
+          $mdlext-light-range-bg-color 100%);
+      }
+
+      &.is-lowest-value:focus:not(:active)::-ms-thumb {
+        background: radial-gradient(circle closest-side,
+          $mdlext-light-range-bg-focus-color 0%,
+          $mdlext-light-range-bg-focus-color 25%,
+          $mdlext-light-range-bg-color 25%,
+          $mdlext-light-range-bg-color 37.5%,
+          $mdlext-light-range-bg-focus-color 37.5%,
+          $mdlext-light-range-bg-focus-color 100%);
+      }
+
+      &.is-lowest-value:active::-ms-thumb {
+        background: radial-gradient(circle closest-side,
+          transparent 0%,
+          transparent 77.78%,
+          $mdlext-light-range-bg-color 77.78%,
+          $mdlext-light-range-bg-color 100%);
+      }
+      /* stylelint-enable */
+
+      &.is-lowest-value::-ms-fill-lower {
+        background: transparent;
+      }
+
+      /**************************** Disabled ****************************/
+
+      &:disabled:focus::-webkit-slider-thumb,
+      &:disabled:active::-webkit-slider-thumb,
+      &:disabled::-webkit-slider-thumb {
+        background: $mdlext-light-range-bg-color;
+      }
+
+      &:disabled:focus::-moz-range-thumb,
+      &:disabled:active::-moz-range-thumb,
+      &:disabled::-moz-range-thumb {
+        background: $mdlext-light-range-bg-color;
+      }
+
+      &:disabled + .mdl-slider__background-flex > .mdl-slider__background-lower {
+        background-color: $mdlext-light-range-bg-color;
+      }
+
+      &.is-lowest-value:disabled:focus::-webkit-slider-thumb,
+      &.is-lowest-value:disabled:active::-webkit-slider-thumb,
+      &.is-lowest-value:disabled::-webkit-slider-thumb {
+        border-color: $mdlext-light-range-bg-color;
+        background: transparent;
+      }
+
+      &.is-lowest-value:disabled:focus::-moz-range-thumb,
+      &.is-lowest-value:disabled:active::-moz-range-thumb,
+      &.is-lowest-value:disabled::-moz-range-thumb {
+        border-color: $mdlext-light-range-bg-color;
+        background: transparent;
+      }
+
+      &:disabled:focus::-ms-thumb,
+      &:disabled:active::-ms-thumb,
+      &:disabled::-ms-thumb {
+        background: $mdlext-light-range-bg-color;
+      }
+
+      /* stylelint-disable */
+      &.is-lowest-value:disabled:focus::-ms-thumb,
+      &.is-lowest-value:disabled:active::-ms-thumb,
+      &.is-lowest-value:disabled::-ms-thumb {
+        background: radial-gradient(circle closest-side,
+          transparent 0%,
+          transparent 50%,
+          $mdlext-light-range-bg-color 50%,
+          $mdlext-light-range-bg-color 100%);
+      }
+
+      &:disabled::-ms-fill-lower {
+        background: linear-gradient(to right,
+          transparent,
+          transparent 25px,
+          $mdlext-light-range-bg-color 25px,
+          $mdlext-light-range-bg-color 0);
+      }
+      /* stylelint-enable */
+
+    }
+  }
+
+  .mdl-slider__background-flex {
+    background: transparent;
+  }
+
+  .mdl-slider__background-lower {
+    background: $mdlext-light-range-color;
+  }
+
+  // This one styles the upper part of the slider track.
+  .mdl-slider__background-upper {
+    background: $mdlext-light-range-bg-color;
+  }
+}
+
+
+// mdl/src/textfield/_textfield.scss
+// -----------------------------------
+.mdlext-light-color-theme {
+
+  .mdl-textfield__input {
+    border-bottom-color: $mdlext-light-input-text-bottom-border-color;
+  }
+  .mdl-textfield.is-invalid .mdl-textfield__input {
+    border-color: $mdlext-light-input-text-error-color;
+  }
+  fieldset[disabled] .mdl-textfield .mdl-textfield__input,
+  .mdl-textfield.is-disabled .mdl-textfield__input {
+    background-color: transparent;
+    border-bottom-color: $mdlext-light-input-text-disabled-color;
+    color: $mdlext-light-input-text-disabled-text-color;
+  }
+  .mdl-textfield__label {
+    color: $mdlext-light-input-text-label-color;
+  }
+  .mdl-textfield__label::after {
+    background-color: $mdlext-light-input-text-highlight-color;
+  }
+  fieldset[disabled] .mdl-textfield .mdl-textfield__label,
+  .mdl-textfield.is-disabled.is-disabled .mdl-textfield__label {
+    color: $mdlext-light-input-text-disabled-text-color;
+  }
+  .mdl-textfield--floating-label.is-focused .mdl-textfield__label,
+  .mdl-textfield--floating-label.is-dirty .mdl-textfield__label,
+  .mdl-textfield--floating-label.has-placeholder .mdl-textfield__label {
+    color: $mdlext-light-input-text-highlight-color;
+  }
+  .mdl-textfield--floating-label.is-invalid .mdl-textfield__label {
+    color: $mdlext-light-input-text-error-color;
+  }
+  .mdl-textfield.is-invalid .mdl-textfield__label::after {
+    background-color: $mdlext-light-input-text-error-color;
+  }
+  .mdl-textfield__error {
+    color: $mdlext-light-input-text-error-color;
+  }
+}
+
+
+// mdl/src/checkbox/_checkbox.scss
+// -----------------------------------
+.mdlext-light-color-theme {
+
+  .mdl-checkbox__box-outline {
+    border-color: $mdlext-light-checkbox-off-color;
+  }
+  .mdl-checkbox.is-checked .mdl-checkbox__box-outline {
+    border-color: $mdlext-light-checkbox-color;
+  }
+  fieldset[disabled] .mdl-checkbox .mdl-checkbox__box-outline,
+  .mdl-checkbox.is-disabled .mdl-checkbox__box-outline {
+    border-color: $mdlext-light-checkbox-disabled-color;
+  }
+
+  .mdl-checkbox__focus-helper {
+    background-color: transparent;
+  }
+  .mdl-checkbox.is-focused.is-checked .mdl-checkbox__focus-helper {
+    box-shadow: 0 0 0 ($checkbox-button-size / 2) $mdlext-light-checkbox-focus-color;
+    background-color: $mdlext-light-checkbox-focus-color;
+  }
+
+  .mdl-checkbox__tick-outline {
+    background: transparent;
+  }
+  .mdl-checkbox.is-checked .mdl-checkbox__tick-outline {
+    background-color: $mdlext-light-checkbox-color;
+  }
+  fieldset[disabled] .mdl-checkbox.is-checked .mdl-checkbox__tick-outline,
+  .mdl-checkbox.is-checked.is-disabled .mdl-checkbox__tick-outline {
+    background-color: $mdlext-light-checkbox-disabled-color;
+  }
+
+  fieldset[disabled] .mdl-checkbox .mdl-checkbox__label,
+  .mdl-checkbox.is-disabled .mdl-checkbox__label {
+    color: $mdlext-light-checkbox-disabled-color;
+  }
+
+  .mdl-checkbox__ripple-container .mdl-ripple {
+    background: $mdlext-light-checkbox-color;
+  }
+  fieldset[disabled] .mdl-checkbox .mdl-checkbox__ripple-container .mdl-ripple,
+  .mdl-checkbox.is-disabled .mdl-checkbox__ripple-container .mdl-ripple {
+    background: transparent;
+  }
+
+}
+
+// mdl/src/radio/_radio.scss
+// -----------------------------------
+.mdlext-light-color-theme {
+  .mdl-radio__outer-circle {
+    border-color: $mdlext-light-radio-off-color;
+  }
+  .mdl-radio.is-checked .mdl-radio__outer-circle {
+    border-color: $mdlext-light-radio-color;
+  }
+  .mdl-radio__outer-circle fieldset[disabled] .mdl-radio,
+  .mdl-radio.is-disabled .mdl-radio__outer-circle {
+    border-color: $mdlext-light-radio-disabled-color;
+  }
+
+  .mdl-radio__inner-circle {
+    background: $mdlext-light-radio-color;
+  }
+  fieldset[disabled] .mdl-radio .mdl-radio__inner-circle,
+  .mdl-radio.is-disabled .mdl-radio__inner-circle {
+    background: $mdlext-light-radio-disabled-color;
+  }
+
+  fieldset[disabled] .mdl-radio .mdl-radio__label,
+  .mdl-radio.is-disabled .mdl-radio__label {
+    color: $mdlext-light-radio-disabled-color;
+  }
+
+  .mdl-radio__ripple-container .mdl-ripple {
+    background: $mdlext-light-radio-color;
+  }
+  fieldset[disabled] .mdl-radio .mdl-radio__ripple-container .mdl-ripple,
+  .mdl-radio.is-disabled .mdl-radio__ripple-container .mdl-ripple {
+    background: transparent;
+  }
+}
+
+// mdl/src/icon-togglr/_icon-toggle.scss
+// ---------------------------------------
+.mdlext-light-color-theme {
+  .mdl-icon-toggle__label {
+    color: $mdlext-light-icon-toggle-color;
+  }
+  .mdl-icon-toggle.is-checked .mdl-icon-toggle__label {
+    color: $mdlext-light-icon-toggle-checked-color;
+  }
+  .mdl-icon-toggle.is-disabled .mdl-icon-toggle__label {
+    color: $mdlext-light-icon-toggle-disabled-color;
+  }
+  .mdl-icon-toggle.is-focused .mdl-icon-toggle__label {
+    background-color: $mdlext-light-icon-toggle-focus-color;
+  }
+  .mdl-icon-toggle.is-focused.is-checked .mdl-icon-toggle__label {
+    background-color: $mdlext-light-icon-toggle-checked-focus-color;
+  }
+  .mdl-icon-toggle__ripple-container .mdl-ripple {
+    background: $mdlext-light-icon-toggle-color;
+  }
+  .mdl-icon-toggle.is-disabled .mdl-icon-toggle__ripple-container .mdl-ripple {
+    background: transparent;
+  }
+}
+
+
+// mdl/src/switch/_switch.scss
+// -----------------------------------
+.mdlext-light-color-theme {
+
+  .mdl-switch__track {
+    background: $mdlext-light-switch-off-track-color;
+  }
+  .mdl-switch.is-checked .mdl-switch__track {
+    background: $mdlext-light-switch-track-color;
+  }
+  .mdl-switch__track fieldset[disabled] .mdl-switch,
+  .mdl-switch.is-disabled .mdl-switch__track {
+    background: $mdlext-light-switch-disabled-track-color;
+  }
+
+  .mdl-switch__thumb {
+    background: $mdlext-light-switch-off-thumb-color;
+  }
+  .mdl-switch.is-checked .mdl-switch__thumb {
+    background: $mdlext-light-switch-thumb-color;
+  }
+  .mdl-switch__thumb fieldset[disabled] .mdl-switch,
+  .mdl-switch.is-disabled .mdl-switch__thumb {
+    background: $mdlext-light-switch-disabled-thumb-color;
+  }
+
+  .mdl-switch__focus-helper {
+    background-color: transparent;
+  }
+  .mdl-switch.is-focused .mdl-switch__focus-helper {
+    background-color: rgba(0, 0, 0, 0.1);
+  }
+  .mdl-switch.is-focused.is-checked .mdl-switch__focus-helper {
+    box-shadow: 0 0 0 (($switch-ripple-size - $switch-helper-size) / 2) $mdlext-light-switch-faded-color;
+    background-color: $mdlext-light-switch-faded-color;
+  }
+
+  .mdl-switch__label fieldset[disabled] .mdl-switch,
+  .mdl-switch.is-disabled .mdl-switch__label {
+    color: $mdlext-light-switch-disabled-thumb-color;
+  }
+
+  .mdl-switch__ripple-container .mdl-ripple {
+    background: $mdlext-light-switch-color;
+  }
+  fieldset[disabled] .mdl-switch .mdl-switch__ripple-container .mdl-ripple,
+  .mdl-switch.is-disabled .mdl-switch__ripple-container .mdl-ripple {
+    background: transparent;
+  }
+}
+
+
+// mdl/src/data-table/_data-table.scss
+// -----------------------------------
+.mdlext-light-color-theme {
+
+  .mdl-data-table {
+    border-color: $mdlext-light-data-table-divider-color;
+    background-color: $mdlext-light-data-table-background-color;
+
+    tbody {
+      tr {
+        &.is-selected {
+          background-color: $mdlext-light-data-table-selection-color;
+        }
+        &:hover {
+          background-color: $mdlext-light-data-table-hover-color;
+        }
+      }
+    }
+    th {
+      color: $data-table-header-color;
+
+      &.mdl-data-table__header--sorted-ascending,
+      &.mdl-data-table__header--sorted-descending {
+        color: $mdlext-light-data-table-header-sorted-color;
+
+        &:hover {
+          &::before {
+            color: $mdlext-light-data-table-header-sorted-icon-hover-color;
+          }
+        }
+      }
+    }
+  }
+}
+
+
+// mdl/src/menu/_menu.scss
+// -----------------------------------
+.mdlext-light-color-theme {
+
+  .mdl-menu__outline {
+    background: $mdlext-light-default-dropdown-bg-color;
+  }
+
+  .mdl-menu__item {
+    color: $mdlext-light-default-item-text-color;
+    background-color: transparent;
+    outline-color: $mdlext-light-default-item-outline-color;
+
+    &--full-bleed-divider {
+      border-bottom-color: $mdlext-light-default-item-divider-color;
+    }
+
+    &[disabled],
+    &[data-mdl-disabled] {
+      color: $mdlext-light-disabled-item-text-color;
+      background-color: transparent;
+
+      &:hover {
+        background-color: transparent;
+      }
+
+      &:focus {
+        background-color: transparent;
+      }
+
+      & .mdl-ripple {
+        background: transparent;
+      }
+    }
+
+    &:hover {
+      background-color: $mdlext-light-default-item-hover-bg-color;
+    }
+
+    &:focus {
+      background-color: $mdlext-light-default-item-focus-bg-color;
+    }
+
+    &:active {
+      background-color: $mdlext-light-default-item-active-bg-color;
+    }
+  }
+}
+
+
+// mdl/src/card/_card.scss
+// ----------------------------------------
+.mdlext-light-color-theme {
+
+  .mdl-card {
+    background: $mdlext-light-card-background-color;
+  }
+
+  .mdl-card__media {
+    background-color: $mdlext-light-card-image-placeholder-color;
+  }
+
+  .mdl-card__title {
+    color: $mdlext-light-card-text-color;
+
+    &.mdl-card--border {
+      border-bottom-color: $mdlext-light-card-border-color;
+    }
+  }
+
+  .mdl-card__title-text {
+    color: inherit;
+  }
+
+  .mdl-card__subtitle-text {
+    color: $mdlext-light-card-subtitle-color;
+  }
+
+  .mdl-card__supporting-text {
+    color: $mdlext-light-card-supporting-text-text-color;
+  }
+
+  .mdl-card__actions {
+    background-color: rgba(0, 0, 0, 0);
+
+    &.mdl-card--border {
+      border-top-color: $mdlext-light-card-border-color;
+    }
+  }
+}
+
+
+// mdlext/src/selectfield/_selectfield.scss
+// ----------------------------------------
+.mdlext-light-color-theme {
+
+  .mdlext-selectfield.is-disabled::after {
+    color: $mdlext-light-input-text-disabled-color;
+    @include mdlext-arrow(bottom, $mdlext-selectfield-arrow-width, $mdlext-selectfield-arrow-length, $mdlext-light-input-text-disabled-color);
+  }
+
+  .mdlext-selectfield__select {
+    border-bottom-color: $mdlext-light-input-text-bottom-border-color;
+    color: inherit;
+
+    option {
+      background-color: $mdlext-light-content-background-color;
+      color: $mdlext-light-text-color-primary;
+    }
+  }
+  .mdlext-selectfield.is-invalid .mdlext-selectfield__select {
+    border-color: $mdlext-light-input-text-error-color;
+  }
+  fieldset[disabled] .mdlext-selectfield .mdlext-selectfield__select,
+  .mdlext-selectfield.is-disabled .mdlext-selectfield__select {
+    background-color: transparent;
+    border-bottom-color: $mdlext-light-input-text-disabled-color;
+    color: $mdlext-light-input-text-disabled-text-color;
+  }
+
+  .mdlext-selectfield__label {
+    color: $mdlext-light-input-text-label-color;
+  }
+  fieldset[disabled] .mdlext-selectfield .mdlext-selectfield__label,
+  .mdlext-selectfield.is-disabled.is-disabled .mdlext-selectfield__label {
+    color: $mdlext-light-input-text-disabled-text-color;
+  }
+  .mdlext-selectfield--floating-label.is-focused .mdlext-selectfield__label,
+  .mdlext-selectfield--floating-label.is-dirty .mdlext-selectfield__label,
+  .mdlext-selectfield--floating-label.is-dirty.is-dirty .mdlext-selectfield__label,
+  .mdlext-selectfield--floating-label.has-placeholder .mdlext-selectfield__label {
+    color: $mdlext-light-input-text-highlight-color;
+  }
+  .mdlext-selectfield--floating-label.is-invalid .mdlext-selectfield__label {
+    color: $mdlext-light-input-text-error-color;
+  }
+  .mdlext-selectfield__label::after {
+    background-color: $mdlext-light-input-text-highlight-color;
+  }
+  .mdlext-selectfield.is-invalid .mdlext-selectfield__label::after {
+    background-color: $mdlext-light-input-text-error-color;
+  }
+
+  .mdlext-selectfield__error {
+    color: $mdlext-light-input-text-error-color;
+  }
+}
+
+// mdlext/src/menu-button/_menu-button.scss
+// ----------------------------------------
+.mdlext-menu.mdlext-light-color-theme {
+  background: $mdlext-light-default-dropdown-bg-color;
+}
+
+.mdlext-light-color-theme {
+
+  .mdlext-menu {
+    background: $mdlext-light-default-dropdown-bg-color;
+
+    &__item {
+      color: $mdlext-light-default-item-text-color;
+      background-color: $mdlext-light-default-dropdown-bg-color;
+
+      &:active,
+      &[aria-selected='true'] {
+        background-color: $mdlext-light-default-item-active-bg-color;
+      }
+      &:hover:not([disabled]) {
+        background-color: $mdlext-light-default-item-hover-bg-color;
+      }
+      &:focus {
+        outline-color: $mdlext-light-default-item-outline-color;
+        background-color: $mdlext-light-default-item-focus-bg-color;
+      }
+      &[disabled] {
+        color: $mdlext-light-disabled-item-text-color;
+
+        > * {
+          color: $mdlext-light-disabled-item-text-color;
+        }
+      }
+    }
+    &__item-separator {
+      border-bottom: 1px solid $mdlext-light-default-item-divider-color;
+    }
+  }
+}
+
+
+// mdlext/src/bordered-fields/_bordered-fields.scss
+// -------------------------------------------------
+.mdlext-light-color-theme {
+
+  .mdlext-bordered-fields {
+
+    .mdl-textfield,
+    .mdlext-selectfield {
+
+      .mdl-textfield__input,
+      .mdlext-selectfield__select {
+        background-color: $mdlext-light-bordered-field-background-color;
+        border-color: $mdlext-light-bordered-field-border-color;
+        color: $mdlext-light-bordered-field-input-text-color;
+
+        &:disabled {
+          color: $mdlext-light-bordered-field-input-text-disabled-text-color;
+          background-color: $mdlext-light-bordered-field-disabled-background-color;
+          border-color: $mdlext-light-bordered-field-disabled-border-color;
+        }
+        &:focus {
+          background-color: $mdlext-light-bordered-field-focus-background-color;
+          border-color: $mdlext-light-bordered-field-focus-border-color;
+        }
+      }
+      &.is-invalid {
+        .mdl-textfield__input,
+        .mdlext-selectfield__select {
+          color: $mdlext-light-bordered-field-input-text-error-color;
+          border-color: $mdlext-light-bordered-field-error-border-color;
+          background-color: $mdlext-light-bordered-field-error-background-color;
+
+          &:focus {
+            border-color: $mdlext-light-bordered-field-error-focus-border-color;
+            background-color: $mdlext-light-bordered-field-error-focus-background-color;
+          }
+        }
+      }
+    }
+
+    fieldset[disabled] .mdlext-selectfield::after,
+    .mdlext-selectfield.is-disabled::after {
+      color: $mdlext-light-bordered-field-input-text-disabled-text-color;
+      @include mdlext-arrow(bottom, $mdlext-selectfield-arrow-width, $mdlext-selectfield-arrow-length, $mdlext-light-bordered-field-input-text-disabled-text-color);
+    }
+
+    fieldset[disabled] .mdl-textfield .mdl-textfield__input,
+    fieldset[disabled] .mdlext-selectfield .mdlext-selectfield__select {
+      color: $mdlext-light-bordered-field-input-text-disabled-text-color;
+      background-color: $mdlext-light-bordered-field-disabled-background-color;
+      border-color: $mdlext-light-bordered-field-disabled-border-color;
+    }
+
+    .mdl-textfield,
+    .mdlext-selectfield {
+
+      .mdl-textfield__label,
+      .mdlext-selectfield__label {
+        color: $mdlext-light-bordered-field-input-text-label-color;
+      }
+      &.mdl-textfield--floating-label.is-focused.is-focused,
+      &.mdl-textfield--floating-label.is-dirty.is-dirty,
+      &.mdl-textfield--floating-label.has-placeholder,
+      &.mdlext-selectfield--floating-label.is-focused.is-focused,
+      &.mdlext-selectfield--floating-label.is-dirty.is-dirty,
+      &.mdlext-selectfield--floating-label.has-placeholder {
+
+        .mdl-textfield__label,
+        .mdlext-selectfield__label {
+          color: $mdlext-light-bordered-field-input-text-label-focus-color;
+        }
+      }
+      &.mdl-textfield--floating-label.is-disabled.is-disabled,
+      &.mdlext-selectfield--floating-label.is-disabled.is-disabled {
+
+        .mdl-textfield__label,
+        .mdlext-selectfield__label {
+          color: $mdlext-light-bordered-field-input-text-label-disabled-color;
+        }
+      }
+      &.mdl-textfield--floating-label.is-invalid.is-invalid,
+      &.mdlext-selectfield--floating-label.is-invalid.is-invalid {
+
+        .mdl-textfield__label,
+        .mdlext-selectfield__label {
+          color: $mdlext-light-bordered-field-input-text-label-error-color;
+        }
+      }
+    }
+
+    fieldset[disabled] .mdl-textfield .mdl-textfield__label,
+    fieldset[disabled] .mdl-selectfield .mdl-selectfield__label {
+      color: $mdlext-light-bordered-field-input-text-label-disabled-color;
+    }
+
+    // Icon(s) and/or button(s) inside textfield
+    .mdl-textfield,
+    .mdlext-selectfield {
+      &.is-disabled i,
+      &.is-disabled .mdl-button {
+        color: $mdlext-light-bordered-field-disabled-border-color;
+      }
+    }
+    fieldset[disabled] .mdl-textfield,
+    fieldset[disabled] .mdlext-selectfield {
+      i,
+      .mdl-button {
+        color: $mdlext-light-bordered-field-disabled-border-color;
+      }
+    }
+  }
+}
+
+
+// mdlext/src/accordion/_accordion.scss
+// ----------------------------------------
+.mdlext-light-color-theme {
+
+  .mdlext-accordion {
+
+    &__tab {
+      color: $mdlext-light-accordion-header-secondary-color;
+      background-color: $mdlext-light-accordion-header-background-color;
+
+      &:focus {
+        outline-color: $mdlext-light-accordion-header-focus-outline-color;
+      }
+      &[aria-expanded='true'] {
+        background-color: $mdlext-light-accordion-header-background-open-color;
+      }
+      &[aria-selected='true'] {
+        background-color: $mdlext-light-accordion-header-background-active-color;
+      }
+      &[disabled] {
+        background-color: $mdlext-light-accordion-header-disabled-color;
+        color: $mdlext-light-accordion-header-secondary-color-disabled;
+        pointer-events: none;
+
+        > * {
+          color: $mdlext-light-accordion-header-secondary-color-disabled;
+        }
+      }
+      &:hover:not([disabled]) {
+        background-color: $mdlext-light-accordion-header-background-hover-color;
+      }
+      &--ripple {
+        &[aria-selected='true']::before {
+          background: $mdlext-light-accordion-ripple-color;
+        }
+      }
+    }
+
+    &__tabpanel {
+      color: $mdlext-light-accordion-content-color;
+      background-color: $mdlext-light-accordion-content-background-color;
+    }
+  }
+
+  // Vertical layout
+  .mdlext-accordion {
+
+    &--vertical {
+
+      .mdlext-accordion__tab {
+        border-top: 1px solid $mdlext-light-accordion-header-border-color;
+
+        &[aria-selected='true']::after {
+          background-color: $mdlext-light-accordion-header-highlight-color;
+        }
+      }
+      .mdlext-accordion__tabpanel {
+        border-top: 1px solid $mdlext-light-accordion-header-border-color;
+      }
+    }
+  }
+
+  // Horizontal layout
+  .mdlext-accordion {
+
+    &--horizontal {
+
+      .mdlext-accordion__tab {
+        border-left: 1px solid $mdlext-light-accordion-header-border-color;
+
+        &[aria-selected='true']::after {
+          background-color: $mdlext-light-accordion-header-highlight-color;
+        }
+      }
+      .mdlext-accordion__tabpanel {
+        border-left: 1px solid $mdlext-light-accordion-header-border-color;
+      }
+    }
+  }
+
+  .mdlext-accordion {
+
+    &__panel:first-child > &__tab {
+      // Use container to set outer borders
+      border-top-color: transparent;
+      border-left-color: transparent;
+    }
+  }
+
+  // Making accordion appear disabled.
+  // Note: does not prevent tabbing into a disabled accordion
+  .mdlext-accordion[disabled] {
+    .mdlext-accordion__tab {
+      background-color: $mdlext-light-accordion-header-disabled-color;
+      color: $mdlext-light-accordion-header-secondary-color-disabled;
+
+      > * {
+        color: $mdlext-light-accordion-header-secondary-color-disabled;
+      }
+    }
+    .mdlext-accordion__tabpanel {
+      opacity: 0.8;
+      filter: blur(1px) grayscale(80%);
+    }
+  }
+}
diff --git a/node_modules/mdl-ext/src/color-themes/readme.md b/node_modules/mdl-ext/src/color-themes/readme.md
new file mode 100644
index 0000000..6266567
--- /dev/null
+++ b/node_modules/mdl-ext/src/color-themes/readme.md
@@ -0,0 +1,104 @@
+# Color Themes
+![Color Themes](../../etc/palette.png)
+
+The **color-themes** component demonstrates how you can create your own themes of 
+[material design colors](https://www.google.com/design/spec/style/color.html).
+
+## Introduction
+Material Design Lite provides only one color theme, but in many web designs more than one theme is required, e.g. a 
+dark theme and a light theme. This component provides the necessary SASS files to use two additional color themes in MDL.
+
+### To include a MDLEXT color theme component:
+&nbsp;1. Code a block element, as the "outer" container, intended to hold all of the color theme.
+```html
+<section>
+</section>
+```
+
+&nbsp;2. Add one of the `mdlext-light-color-theme` or `mdlext-dark-color-theme` classes to the block element using the `class` attribute.
+```html
+<section class="mdlext-light-color-theme">
+</section>
+```
+
+&nbsp;3. Add the MDL components that shuld be rendered with the spesified color theme.
+```html
+<section class="mdlext-light-color-theme">
+  <div class="mdl-card mdl-shadow--2dp">
+    <header class="mdl-card__title mdl-color--primary mdl-color-text--primary-contrast">
+      <button class="mdl-button mdl-button--icon mdl-js-button mdl-js-ripple-effect">
+        <i class="material-icons">view_headline</i>
+      </button>
+      <h2 class="mdl-card__title-text">A card with a Color Theme</h2>
+      <div class="mdl-layout-spacer"></div>
+      <button class="mdl-button mdl-button--icon mdl-js-button mdl-js-ripple-effect">
+        <i class="material-icons">share</i>
+      </button>
+    </header>
+    <div class="mdl-card__supporting-text">
+      Some supporting text ...
+    </div>
+    <footer class="mdl-card__actions mdl-card--border">
+      <a class="mdl-button mdl-button--colored mdl-js-button mdl-js-ripple-effect">
+        Read more
+      </a>
+      <div class="mdl-layout-spacer"></div>
+      <button class="mdl-button mdl-button--icon mdl-button--colored"><i class="material-icons">share</i></button>
+    </footer>
+  </div>
+  <p>More content ...</p>
+</section>  
+```
+
+### Create your own color theme
+Creating your own color theme is simple. For each of the themes, light or dark, you must modify six SASS variables. 
+The variables defines the primary and accent colors for the theme, and their corresponding contrast colors. 
+
+Start by picking some sensible primary and accent colors from the 
+[material color plaette](https://www.google.com/design/spec/style/color.html#color-color-palette) - or use one of the
+web based platte generators as an aid. The [material palette](http://www.materialpalette.com/) is used for this example.
+ 
+Pick a primary and an accent color from the [material palette](http://www.materialpalette.com/), e.g. grey/yellow.
+Download the SASS version of the palette and translate the variables to the MDLEXT color theme.
+
+The downloaded material palette SASS variables:
+```sass
+$primary-color-dark:   #616161
+$primary-color:        #9E9E9E
+$primary-color-light:  #F5F5F5
+$primary-color-text:   #212121
+$accent-color:         #FFEB3B
+$primary-text-color:   #212121
+$secondary-text-color: #727272
+$divider-color:        #B6B6B6
+```
+
+Open the MDLEXT [color-themes](./_color-themes.scss) SASS file and translate material palette variables to MDLEXT color theme:
+```sass
+$mdlext-light-color-primary:          #9E9E9E;
+$mdlext-light-color-primary-dark:     #616161;
+$mdlext-light-color-primary-light:    #9E9E9E; // Fallback color. Set to color-primary if fallback is not needed
+$mdlext-light-color-primary-contrast: #F5F5F5;  
+$mdlext-light-color-accent:           #FFEB3B; 
+$mdlext-light-color-accent-light:     #FFEB3B; // Fallback color. Set to color-primary if fallback is not needed
+$mdlext-light-color-accent-contrast:  #FFFFFF;
+```
+
+Save the modified variables to your own SASS project, recompile and try out your new theme.
+
+There are a few more SASS variables you can modify - and they should be relativeley self explanatory. By default these 
+values are set in accordance with the guidance given in the 
+[material design colors](https://www.google.com/design/spec/style/color.html) guide.
+
+#### Examples
+See the [example code](./snippets/color-themes.html).
+
+## Configuration options
+
+The MDLEXT CSS classes apply various predefined visual and behavioral enhancements to MDL components. 
+The table below lists the available classes and their effects.
+
+| MDLEXT class | Effect | Remarks |
+|-----------|--------|---------|
+| `mdlext-light-color-theme` | Defines container as an MDLEXT light color theme component | Required on an "outer" block element|
+| `mdlext-dark-color-theme` | Defines container as an MDLEXT dark coolor theme component | Required on an "outer" block element|
diff --git a/node_modules/mdl-ext/src/color-themes/snippets/color-themes.html b/node_modules/mdl-ext/src/color-themes/snippets/color-themes.html
new file mode 100644
index 0000000..1dc8ae5
--- /dev/null
+++ b/node_modules/mdl-ext/src/color-themes/snippets/color-themes.html
@@ -0,0 +1,2769 @@
+<style>
+  .demo-theme-container {
+    margin: 0 auto 32px;
+    /*max-width: 800px;*/
+  }
+
+  .demo-theme-container table.info,
+  .demo-card-grid table.info {
+    width: 100%
+  }
+  .demo-theme-container table.info th,
+  .demo-card-grid table.info th {
+    padding-right: 40px;
+    vertical-align: middle;
+    text-align: left;
+    width: 30%;
+  }
+  .demo-theme-container section,
+  .demo-card-grid section {
+    margin: 0 16px;
+  }
+
+  .demo-badge-grid {
+  }
+  .demo-badge-grid .mdl-cell {
+    text-align: center;
+  }
+  .demo-badge-grid .mdl-cell p {
+    margin-top: 32px;
+  }
+
+  .demo-button-grid {
+  }
+  .demo-button-grid .mdl-cell {
+    text-align: center;
+    padding: 12px 4px;
+  }
+
+  .demo-toggle-grid {
+  }
+  .demo-toggle-grid .mdl-cell p {
+    margin-top: 16px;
+  }
+
+  .demo-slider-grid  {
+  }
+  .demo-slider-grid p {
+    margin-top: 16px;
+  }
+
+  .textfield-demo-container {
+  }
+
+  .textfield-demo-container .mdl-cell {
+    padding: 0 4px 8px 0;
+  }
+
+  .textfield-demo-container .mdl-cell p {
+    margin-bottom: 0;
+    white-space: nowrap;
+    text-overflow: ellipsis;
+    overflow: hidden;
+  }
+
+
+  .demo-menu {
+    padding-top: 16px;
+    max-width: 300px;
+  }
+  .demo-menu-container {
+    position: relative;
+    width: 100%;
+  }
+  .demo-menu-bar {
+    box-sizing: border-box;
+    height: 64px;
+    width: 100%;
+    padding: 16px;
+  }
+  .demo-menu-background-light {
+    background: white;
+    height: 148px;
+    width: 100%;
+  }
+  .demo-menu-background-dark {
+    background: #212121;
+    height: 148px;
+    width: 100%;
+  }
+
+
+  .mdl-card {
+    width: auto;
+  }
+  .mdl-card__media {
+    margin: 0;
+    text-align: center;
+  }
+  .mdl-card__media > img {
+    max-width: 100%;
+    height: auto;
+  }
+  .mdl-card__supporting-text {
+    width: auto;
+  }
+  .mdl-card__actions {
+    display: flex;
+  }
+
+
+  .borderedfield-demo-container .mdl-cell {
+    padding: 0 4px 8px 0;
+  }
+
+  .borderedfield-demo-container .mdl-cell p {
+    margin-bottom: 0;
+    white-space: nowrap;
+    text-overflow: ellipsis;
+    overflow: hidden;
+  }
+
+  /* File input example */
+  .mdl-button--file input {
+    cursor: pointer;
+    opacity: 0;
+    width: 1px;
+    height: 1px;
+  }
+
+</style>
+
+
+<datalist id="languages">
+  <option value="HTML">
+  <option value="CSS">
+  <option value="JavaScript">
+  <option value="Java">
+  <option value="Ruby">
+  <option value="PHP">
+  <option value="Go">
+  <option value="Erlang">
+  <option value="Python">
+  <option value="C">
+  <option value="C#">
+  <option value="C++">
+</datalist>
+
+
+<div class="mdl-grid demo-card-grid" style="margin-bottom: 32px;">
+
+  <div class="mdl-cell mdl-cell--6-col mdl-cell--4-col-tablet mdl-cell--4-col-phone mdlext-light-color-theme">
+    <div class="mdl-card mdl-shadow--2dp">
+      <header class="mdl-card__title mdl-color--primary mdl-color-text--primary-contrast">
+        <button class="mdl-button mdl-button--icon mdl-js-button mdl-js-ripple-effect">
+          <i class="material-icons">view_headline</i>
+        </button>
+        <h2 class="mdl-card__title-text">Light Theme</h2>
+        <div class="mdl-layout-spacer"></div>
+        <button class="mdl-button mdl-button--icon mdl-js-button mdl-js-ripple-effect">
+          <i class="material-icons">share</i>
+        </button>
+      </header>
+      <figure class="mdl-card__media">
+        <img src="./images/_DSC7535-2.jpg" alt="">
+      </figure>
+      <section style="margin-top:16px">
+        <table class="info">
+          <tr>
+            <th class="mdl-typography--caption-color-contrast">primary-dark</th>
+            <td class="mdl-color--primary-dark mdl-color-text--primary-contrast">primary dark</td>
+          </tr>
+          <tr>
+            <th class="mdl-typography--caption-color-contrast">primary</th>
+            <td class="mdl-color--primary mdl-color-text--primary-contrast">primary</td>
+          </tr>
+          <tr>
+            <th class="mdl-typography--caption-color-contrast">accent</th>
+            <td class="mdl-color--accent mdl-color-text--accent-contrast">accent</td>
+          </tr>
+          <tr>
+            <th class="mdl-typography--caption-color-contrast">primary-dark</th>
+            <td class="mdl-color--primary-contrast mdl-color-text--primary-dark">primary dark, inverted</td>
+          </tr>
+          <tr>
+            <th class="mdl-typography--caption-color-contrast">primary</th>
+            <td class="mdl-color--primary-contrast mdl-color-text--primary">primary, inverted</td>
+          </tr>
+          <tr>
+            <th class="mdl-typography--caption-color-contrast">accent</th>
+            <td class="mdl-color--accent-contrast mdl-color-text--accent">accent, inverted</td>
+          </tr>
+        </table>
+      </section>
+
+      <div class="mdl-card__supporting-text">
+        Card Supporting Text
+      </div>
+
+      <footer class="mdl-card__actions mdl-card--border">
+        <a class="mdl-button mdl-button--colored mdl-js-button mdl-js-ripple-effect">
+          Read more
+        </a>
+        <div class="mdl-layout-spacer"></div>
+        <button class="mdl-button mdl-button--icon"><i class="material-icons">radio</i></button>
+        <button class="mdl-button mdl-button--icon mdl-button--colored"><i class="material-icons">favorite</i></button>
+        <button class="mdl-button mdl-button--icon mdl-button--colored"><i class="material-icons">share</i></button>
+      </footer>
+    </div>
+
+  </div>
+
+
+  <div class="mdl-cell mdl-cell--6-col mdl-cell--4-col-tablet mdl-cell--4-col-phone mdlext-dark-color-theme">
+
+    <div class="mdl-card mdl-shadow--2dp">
+      <header class="mdl-card__title mdl-color--primary mdl-color-text--primary-contrast">
+        <button class="mdl-button mdl-button--icon mdl-js-button mdl-js-ripple-effect">
+          <i class="material-icons">view_headline</i>
+        </button>
+        <h2 class="mdl-card__title-text">Dark Theme</h2>
+        <div class="mdl-layout-spacer"></div>
+        <button class="mdl-button mdl-button--icon mdl-js-button mdl-js-ripple-effect">
+          <i class="material-icons">share</i>
+        </button>
+      </header>
+      <figure class="mdl-card__media">
+        <img src="./images/_DSC7535-2.jpg" alt="">
+      </figure>
+      <section style="margin-top:16px">
+        <table class="info">
+          <tr>
+            <th class="mdl-typography--caption-color-contrast">primary-dark</th>
+            <td class="mdl-color--primary-dark mdl-color-text--primary-contrast">primary dark</td>
+          </tr>
+          <tr>
+            <th class="mdl-typography--caption-color-contrast">primary</th>
+            <td class="mdl-color--primary mdl-color-text--primary-contrast">primary</td>
+          </tr>
+          <tr>
+            <th class="mdl-typography--caption-color-contrast">accent</th>
+            <td class="mdl-color--accent mdl-color-text--accent-contrast">accent</td>
+          </tr>
+          <tr>
+            <th class="mdl-typography--caption-color-contrast">primary-dark</th>
+            <td class="mdl-color--primary-contrast mdl-color-text--primary-dark">primary dark, inverted</td>
+          </tr>
+          <tr>
+            <th class="mdl-typography--caption-color-contrast">primary</th>
+            <td class="mdl-color--primary-contrast mdl-color-text--primary">primary, inverted</td>
+          </tr>
+          <tr>
+            <th class="mdl-typography--caption-color-contrast">accent</th>
+            <td class="mdl-color--accent-contrast mdl-color-text--accent">accent, inverted</td>
+          </tr>
+        </table>
+      </section>
+
+      <div class="mdl-card__supporting-text">
+        Card Supporting Text
+      </div>
+
+      <footer class="mdl-card__actions mdl-card--border">
+        <a class="mdl-button mdl-button--colored mdl-js-button mdl-js-ripple-effect">
+          Read more
+        </a>
+        <div class="mdl-layout-spacer"></div>
+        <button class="mdl-button mdl-button--icon"><i class="material-icons">radio</i></button>
+        <button class="mdl-button mdl-button--icon mdl-button--colored"><i class="material-icons">favorite</i></button>
+        <button class="mdl-button mdl-button--icon mdl-button--colored"><i class="material-icons">share</i></button>
+      </footer>
+    </div>
+
+  </div>
+
+</div>
+
+
+
+
+<h2>Light Color Theme</h2>
+
+<div class="demo-theme-container mdlext-light-color-theme">
+
+  <section>
+    <table class="info">
+      <tr>
+        <th class="mdl-typography--caption-color-contrast">.mdl-typography--</th>
+        <td class="mdl-typography--title">Scale &amp; Basic Styles</td>
+      </tr>
+      <tr>
+        <th class="mdl-typography--caption-color-contrast">display-4</th>
+        <td class="mdl-typography--display-4">Light 112px</td>
+      </tr>
+      <tr>
+        <th class="mdl-typography--caption-color-contrast">display-3</th>
+        <td class="mdl-typography--display-3">Regular 56px</td>
+      </tr>
+      <tr>
+        <th class="mdl-typography--caption-color-contrast">display-2</th>
+        <td class="mdl-typography--display-2">Regular 45px</td>
+      </tr>
+      <tr>
+        <th class="mdl-typography--caption-color-contrast">display-1</th>
+        <td class="mdl-typography--display-1">Regular 34px</td>
+      </tr>
+      <tr>
+        <th class="mdl-typography--caption-color-contrast">headline</th>
+        <td class="mdl-typography--headline">Regular 24px</td>
+      </tr>
+      <tr>
+        <th class="mdl-typography--caption-color-contrast">title</th>
+        <td class="mdl-typography--title">Medium 20px</td>
+      </tr>
+      <tr>
+        <th class="mdl-typography--caption-color-contrast">subhead</th>
+        <td class="mdl-typography--subhead">Regular 16px (Device), Regular 15px (Desktop)</td>
+      </tr>
+      <tr>
+        <th class="mdl-typography--caption-color-contrast">body-2</th>
+        <td class="mdl-typography--body-2">Medium 14px (Device), Medium 13px (Desktop)</td>
+      </tr>
+      <tr>
+        <th class="mdl-typography--caption-color-contrast">body-1</th>
+        <td class="mdl-typography--body-1">Regular 14px (Device), Regular 13px (Desktop)</td>
+      </tr>
+      <tr>
+        <th class="mdl-typography--caption-color-contrast">body-2-force-preferred-font</th>
+        <td class="mdl-typography--body-2-force-preferred-font">Medium 14px (Device), Medium 13px (Desktop)</td>
+      </tr>
+      <tr>
+        <th class="mdl-typography--caption-color-contrast">body-1-force-preferred-font</th>
+        <td class="mdl-typography--body-1-force-preferred-font">Regular 14px (Device), Regular 13px (Desktop)</td>
+      </tr>
+      <tr>
+        <th class="mdl-typography--caption-color-contrast">caption</th>
+        <td class="mdl-typography--caption">Regular 12px</td>
+      </tr>
+      <tr>
+        <th class="mdl-typography--caption-color-contrast">menu</th>
+        <td class="mdl-typography--menu">Medium 14px (Device), Medium 13px (Desktop)</td>
+      </tr>
+      <tr>
+        <th class="mdl-typography--caption-color-contrast">button</th>
+        <td class="mdl-typography--button">Medium (All Caps) 14px</td>
+      </tr>
+
+      <tr>
+        <th class="mdl-typography--caption-color-contrast">primary-dark</th>
+        <td class="mdl-color--primary-dark mdl-color-text--primary-contrast">mdl-color--primary-dark mdl-color-text--primary-contrast</td>
+      </tr>
+      <tr>
+        <th class="mdl-typography--caption-color-contrast">primary</th>
+        <td class="mdl-color--primary mdl-color-text--primary-contrast">mdl-color--primary mdl-color-text--primary-contrast</td>
+      </tr>
+      <tr>
+        <th class="mdl-typography--caption-color-contrast">accent</th>
+        <td class="mdl-color--accent mdl-color-text--accent-contrast">mdl-color--accent mdl-color-text--accent-contrast</td>
+      </tr>
+      <tr>
+        <th class="mdl-typography--caption-color-contrast">primary-dark</th>
+        <td class="mdl-color--primary-contrast mdl-color-text--primary-dark">mdl-color--primary-contrast mdl-color-text--primary-dark</td>
+      </tr>
+      <tr>
+        <th class="mdl-typography--caption-color-contrast">primary</th>
+        <td class="mdl-color--primary-contrast mdl-color-text--primary">mdl-color-text--primary</td>
+      </tr>
+      <tr>
+        <th class="mdl-typography--caption-color-contrast">accent</th>
+        <td class="mdl-color--accent-contrast mdl-color-text--accent">mdl-color--accent-contrast mdl-color-text--accent</td>
+      </tr>
+    </table>
+  </section>
+
+  <section>
+    <h1>Base font</h1>
+
+    <p>Material Design Lite start’s with a base font of</p>
+    <ul>
+      <li>A size of 14px</li>
+      <li>A weight of 400</li>
+      <li>A line height of 20px</li>
+    </ul>
+
+    <p class="mdl-typography--body-1">Regular 14px (Device), Regular 13px (Desktop)</p>
+    <p class="mdl-typography--body-1-force-preferred-font">Regular 14px (Device), Regular 13px (Desktop)</p>
+    <p class="mdl-typography--body-2">Medium 14px (Device), Medium 13px (Desktop)</p>
+    <p class="mdl-typography--body-2-color-contrast">Body with color contrast</p>
+    <p class="mdl-typography--body-2-force-preferred-font">Medium 14px (Device), Medium 13px (Desktop)</p>
+    <p><a href="#" onclick="return false">An anchor</a></p>
+
+    <h1>Headings</h1>
+    <h1>h1 (56px) <small>Subtitle</small></h1>
+    <h2>h2 (45px) <small>Subtitle</small></h2>
+    <h3>h3 (34px) <small>Subtitle</small></h3>
+    <h4>h4 (24px) <small>Subtitle</small></h4>
+    <h5>h5 (20px) <small>Subtitle</small></h5>
+    <h6>h6 (16px) <small>Subtitle</small></h6>
+  </section>
+
+
+  <!-- textfields -->
+  <section class = "textfield-demo-container">
+
+    <div class="mdl-grid mdl-grid--no-spacing">
+
+      <div class="mdl-cell mdl-cell--4-col">
+        <div class="mdl-textfield mdl-js-textfield">
+          <input class="mdl-textfield__input" type="text">
+          <label class="mdl-textfield__label">Text...</label>
+        </div>
+      </div>
+
+      <div class="mdl-cell mdl-cell--4-col">
+        <div class="mdl-textfield mdl-js-textfield">
+          <input class="mdl-textfield__input" type="text" pattern="-?[0-9]*(\.[0-9]+)?">
+          <label class="mdl-textfield__label">Number...</label>
+          <span class="mdl-textfield__error">Input is not a number!</span>
+        </div>
+      </div>
+
+      <div class="mdl-cell mdl-cell--4-col">
+        <div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label">
+          <input class="mdl-textfield__input" type="text" list="languages" placeholder="Select a programming language" required>
+          <label class="mdl-textfield__label">Programming Language</label>
+        </div>
+      </div>
+
+      <div class="mdl-cell mdl-cell--4-col">
+        <div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label">
+          <input class="mdl-textfield__input" type="text" pattern="-?[0-9]*(\.[0-9]+)?">
+          <label class="mdl-textfield__label">Number...</label>
+          <span class="mdl-textfield__error">Input is not a number!</span>
+        </div>
+      </div>
+
+      <div class="mdl-cell mdl-cell--4-col">
+        <div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label">
+          <input class="mdl-textfield__input" type="text" pattern="-?[0-9]*(\.[0-9]+)?" disabled value="123">
+          <label class="mdl-textfield__label">Number...</label>
+          <span class="mdl-textfield__error">Input is not a number!</span>
+        </div>
+      </div>
+
+      <div class="mdl-cell mdl-cell--4-col">
+        <div class="mdl-textfield mdl-js-textfield mdl-textfield--expandable mdl-textfield--floating-label">
+          <label class="mdl-button mdl-js-button mdl-button--icon" for="mdl-expandable-demo3">
+            <i class="material-icons">search</i>
+          </label>
+          <div class="mdl-textfield__expandable-holder">
+            <input class="mdl-textfield__input" type="text" name="q" value="" id="mdl-expandable-demo3" pattern=".{3,}" />
+            <label class="mdl-textfield__label" for="mdl-expandable-demo1">Expandable Input</label>
+          </div>
+        </div>
+      </div>
+
+      <div class="mdl-cell mdl-cell--8-col">
+        <div class="mdl-textfield mdl-js-textfield mdl-textfield--full-width mdl-textfield--floating-label">
+          <textarea class="mdl-textfield__input" rows= "3"></textarea>
+          <label class="mdl-textfield__label">Text lines...</label>
+        </div>
+      </div>
+
+    </div>
+
+  </section>
+
+
+  <!-- Selectfield -->
+  <section style="margin-bottom: 16px;">
+    <div class="mdl-grid mdl-grid--no-spacing">
+
+      <div class="mdl-cell mdl-cell--4-col">
+        <div class="mdlext-selectfield mdlext-js-selectfield">
+          <select class="mdlext-selectfield__select">
+            <option value=""></option>
+            <option value="option1">option 1</option>
+            <option value="option2">option 2</option>
+            <option value="option3">option 3</option>
+            <option value="option4">option 4</option>
+            <option value="option5">option 5</option>
+          </select>
+          <label class="mdlext-selectfield__label">Profession</label>
+        </div>
+      </div>
+
+      <div class="mdl-cell mdl-cell--4-col">
+        <div class="mdlext-selectfield mdlext-js-selectfield mdlext-selectfield--floating-label">
+          <select class="mdlext-selectfield__select">
+            <option value=""></option>
+            <option value="option1">option 1</option>
+            <option value="option2">option 2</option>
+            <option value="option3">option 3</option>
+            <option value="option4">option 4</option>
+            <option value="option5">option 5</option>
+          </select>
+          <label class="mdlext-selectfield__label">Profession</label>
+        </div>
+      </div>
+
+      <div class="mdl-cell mdl-cell--4-col">
+        <div class="mdlext-selectfield mdlext-js-selectfield mdlext-selectfield--floating-label">
+          <select class="mdlext-selectfield__select" disabled>
+            <option value=""></option>
+            <option value="option1">option 1</option>
+            <option value="option2">option 2</option>
+            <option value="option3">option 3</option>
+            <option value="option4">option 4</option>
+            <option value="option5">option 5</option>
+          </select>
+          <label class="mdlext-selectfield__label">Profession</label>
+        </div>
+      </div>
+    </div>
+  </section>
+
+
+  <!-- bordered fields -->
+  <section class="mdlext-bordered-fields" style="margin-top:16px;">
+
+    <div class="mdl-grid mdl-grid--no-spacing">
+
+      <div class="mdl-cell mdl-cell--4-col">
+        <div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label">
+          <input class="mdl-textfield__input" type="text" list="languages" placeholder="Select a language" required>
+          <label class="mdl-textfield__label">Programming language</label>
+        </div>
+      </div>
+
+      <div class="mdl-cell mdl-cell--4-col">
+        <div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label">
+          <input class="mdl-textfield__input" type="text" pattern="-?[0-9]*(\.[0-9]+)?">
+          <label class="mdl-textfield__label">Numeric with floating label</label>
+          <span class="mdl-textfield__error">Input is not a number!</span>
+        </div>
+      </div>
+
+      <div class="mdl-cell mdl-cell--4-col">
+        <div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label">
+          <input class="mdl-textfield__input" type="text" pattern="-?[0-9]*(\.[0-9]+)?" disabled value="123">
+          <label class="mdl-textfield__label" >Disabled floating label</label>
+          <span class="mdl-textfield__error">Input is not a number!</span>
+        </div>
+      </div>
+
+      <div class="mdl-cell mdl-cell--4-col">
+        <div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label mdlext-bordered-fields__icon-right ">
+          <input class="mdl-textfield__input" type="text" id="uploadfile12" readonly>
+          <label class="mdl-textfield__label">File (work in progress)</label>
+
+          <label class="mdl-button mdl-js-button mdl-button--primary mdl-button--icon mdl-button--file" for="uploadfile12">
+            <i class="material-icons">attach_file</i>
+            <input type="file" id="uploadBtn12">
+          </label>
+        </div>
+        <!--
+          // Need a script to work properly - something like this
+        -->
+        <script>
+          (function() {
+            'use strict';
+            document.querySelector('#uploadBtn12').addEventListener('change', function() {
+              var n = document.querySelector("#uploadfile12");
+              n.value = this.files[0].name;
+              n.parentNode.classList.add('is-dirty');
+            });
+          }());
+        </script>
+      </div>
+
+      <div class="mdl-cell mdl-cell--4-col">
+        <div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label mdlext-bordered-fields__icon-left mdlext-bordered-fields__icon-right">
+          <i class="material-icons">radio</i>
+          <input class="mdl-textfield__input" type="text" disabled>
+          <label class="mdl-textfield__label">Text, disabled</label>
+          <i class="material-icons">fingerprint</i>
+        </div>
+      </div>
+
+
+      <div class="mdl-cell mdl-cell--4-col">
+        <div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label mdlext-bordered-fields__icon-left">
+          <label class="mdl-button mdl-js-button mdl-button--icon">
+            <i class="material-icons">phone</i>
+          </label>
+
+          <input class="mdl-textfield__input" type="text">
+          <label class="mdl-textfield__label">Text...</label>
+        </div>
+      </div>
+
+      <div class="mdl-cell mdl-cell--4-col">
+        <div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label mdlext-bordered-fields__icon-right">
+          <input class="mdl-textfield__input" type="text">
+          <label class="mdl-textfield__label">Text...</label>
+
+          <label class="mdl-button mdl-js-button mdl-button--icon">
+            <i class="material-icons">settings_voice</i>
+          </label>
+        </div>
+      </div>
+
+
+      <div class="mdl-cell mdl-cell--4-col">
+        <div class="mdlext-selectfield mdlext-js-selectfield mdlext-selectfield--floating-label">
+          <select class="mdlext-selectfield__select">
+            <option value=""></option>
+            <option value="option1">option 1</option>
+            <option value="option2">option 2</option>
+            <option value="option3">option 3</option>
+            <option value="option4">option 4</option>
+            <option value="option5">option 5</option>
+          </select>
+          <label class="mdlext-selectfield__label">Profession</label>
+        </div>
+      </div>
+
+      <div class="mdl-cell mdl-cell--4-col">
+        <div class="mdlext-selectfield mdlext-js-selectfield mdlext-selectfield--floating-label">
+          <select class="mdlext-selectfield__select" disabled>
+            <option value=""></option>
+            <option value="option1">option 1</option>
+            <option value="option2">option 2</option>
+            <option value="option3">option 3</option>
+            <option value="option4">option 4</option>
+            <option value="option5">option 5</option>
+          </select>
+          <label class="mdlext-selectfield__label">Profession</label>
+        </div>
+      </div>
+
+      <div class="mdl-cell mdl-cell--4-col">
+        <div class="mdlext-selectfield mdlext-js-selectfield mdlext-selectfield--floating-label mdlext-bordered-fields__icon-left">
+          <label class="mdl-button mdl-js-button mdl-button--icon">
+            <i class="material-icons">phone</i>
+          </label>
+          <select class="mdlext-selectfield__select">
+            <option value=""></option>
+            <option value="option1">option 1</option>
+            <option value="option2">option 2</option>
+            <option value="option3">option 3</option>
+            <option value="option4">option 4</option>
+            <option value="option5">option 5</option>
+          </select>
+          <label class="mdlext-selectfield__label">Profession</label>
+        </div>
+      </div>
+
+      <div class="mdl-cell mdl-cell--4-col">
+        <div class="mdlext-selectfield mdlext-js-selectfield mdlext-selectfield--floating-label mdlext-bordered-fields__icon-left">
+          <label class="mdl-button mdl-js-button mdl-button--icon">
+            <i class="material-icons">phone</i>
+          </label>
+          <select class="mdlext-selectfield__select" disabled>
+            <option value=""></option>
+            <option value="option1">option 1</option>
+            <option value="option2">option 2</option>
+            <option value="option3">option 3</option>
+            <option value="option4">option 4</option>
+            <option value="option5">option 5</option>
+          </select>
+          <label class="mdlext-selectfield__label">Profession</label>
+        </div>
+      </div>
+
+
+
+      <div class="mdl-cell mdl-cell--4-col">
+        <div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label mdlext-bordered-fields__icon-left">
+          <i class="material-icons">radio</i>
+          <input class="mdl-textfield__input" type="text">
+          <label class="mdl-textfield__label">Text...</label>
+        </div>
+      </div>
+
+      <div class="mdl-cell mdl-cell--4-col">
+        <div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label mdlext-bordered-fields__icon-right">
+          <input class="mdl-textfield__input" type="text">
+          <label class="mdl-textfield__label">Text...</label>
+          <i class="material-icons">fingerprint</i>
+        </div>
+      </div>
+
+      <div class="mdl-cell mdl-cell--4-col">
+        <div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label mdlext-bordered-fields__icon-left mdlext-bordered-fields__icon-right">
+          <i class="material-icons">radio</i>
+          <input class="mdl-textfield__input" type="text">
+          <label class="mdl-textfield__label">Text...</label>
+          <i class="material-icons">fingerprint</i>
+        </div>
+      </div>
+
+      <div class="mdl-cell mdl-cell--4-col">
+        <div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label mdlext-bordered-fields__icon-left mdlext-bordered-fields__icon-right">
+          <label class="mdl-button mdl-js-button mdl-button--icon">
+            <i class="material-icons">phone</i>
+          </label>
+
+          <input class="mdl-textfield__input" type="text">
+          <label class="mdl-textfield__label">Text...</label>
+
+          <label class="mdl-button mdl-js-button mdl-button--icon">
+            <i class="material-icons">settings_voice</i>
+          </label>
+        </div>
+      </div>
+
+      <div class="mdl-cell mdl-cell--4-col">
+        <div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label mdlext-bordered-fields__icon-left mdlext-bordered-fields__icon-right">
+          <label class="mdl-button mdl-js-button mdl-button--icon">
+            <i class="material-icons">phone</i>
+          </label>
+
+          <input class="mdl-textfield__input" type="text" disabled>
+          <label class="mdl-textfield__label">Text...</label>
+
+          <label class="mdl-button mdl-js-button mdl-button--icon">
+            <i class="material-icons">settings_voice</i>
+          </label>
+        </div>
+      </div>
+
+      <div class="mdl-cell mdl-cell--4-col">
+        <div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label mdlext-bordered-fields__icon-left mdlext-bordered-fields__icon-right">
+          <i class="material-icons">radio</i>
+          <input class="mdl-textfield__input" type="text">
+          <label class="mdl-textfield__label">Text...</label>
+          <label class="mdl-button mdl-js-button mdl-button--icon">
+            <i class="material-icons">settings_voice</i>
+          </label>
+        </div>
+      </div>
+
+    </div>
+
+    <fieldset disabled>
+      <legend>Disabled fieldset</legend>
+      <div class="mdlext-selectfield mdlext-js-selectfield mdlext-selectfield--floating-label">
+        <select class="mdlext-selectfield__select">
+          <option value=""></option>
+          <option value="option1">option 1</option>
+          <option value="option2">option 2</option>
+          <option value="option3">option 3</option>
+          <option value="option4">option 4</option>
+          <option value="option5">option 5</option>
+          <option value="option6">option 5 abcdefghijklmnopqrstuvw0123456789</option>
+        </select>
+        <label class="mdlext-selectfield__label">Profession</label>
+      </div>
+
+      <div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label">
+        <input class="mdl-textfield__input" type="text" pattern="-?[0-9]*(\.[0-9]+)?">
+        <label class="mdl-textfield__label">Number...</label>
+        <span class="mdl-textfield__error">Input is not a number!</span>
+      </div>
+
+      <div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label mdlext-bordered-fields__icon-left mdlext-bordered-fields__icon-right">
+        <i class="material-icons">radio</i>
+        <input class="mdl-textfield__input" type="text">
+        <label class="mdl-textfield__label">Text...</label>
+        <label class="mdl-button mdl-js-button mdl-button--icon">
+          <i class="material-icons">settings_voice</i>
+        </label>
+      </div>
+    </fieldset>
+
+  </section>
+
+
+  <!-- Badges -->
+  <section style="margin-top:16px">
+    <div class="mdl-grid demo-badge-grid">
+      <div class="mdl-cell mdl-cell--2-col">
+        <span class="mdl-badge" data-badge="4">Inbox</span>
+      </div>
+      <div class="mdl-cell mdl-cell--2-col">
+        <span class="material-icons mdl-badge" data-badge="1">account_box</span>
+      </div>
+      <div class="mdl-cell mdl-cell--2-col">
+        <span class="mdl-badge" data-badge="♥">Mood</span>
+      </div>
+      <div class="mdl-cell mdl-cell--2-col">
+        <span class="material-icons mdl-badge" data-badge="♥">account_box</span>
+      </div>
+      <div class="mdl-cell mdl-cell--2-col">
+        <a href="#" onclick="return false" class="mdl-badge" data-badge="5">Inbox</a>
+      </div>
+    </div>
+  </section>
+
+  <!-- Buttons -->
+  <section>
+    <div class="mdl-grid demo-button-grid">
+      <div class="mdl-cell mdl-cell--2-col mdl-cell--middle">
+        <button class="mdl-button mdl-js-button mdl-button--fab mdl-button--colored">
+          <i class="material-icons">add</i>
+        </button>
+      </div>
+      <div class="mdl-cell mdl-cell--2-col mdl-cell--middle">
+        <button class="mdl-button mdl-js-button mdl-button--fab">
+          <i class="material-icons">add</i>
+        </button>
+      </div>
+      <div class="mdl-cell mdl-cell--2-col mdl-cell--middle">
+        <button class="mdl-button mdl-js-button mdl-button--fab" disabled>
+          <i class="material-icons">add</i>
+        </button>
+      </div>
+
+      <div class="mdl-cell mdl-cell--2-col mdl-cell--middle">
+        <button class="mdl-button mdl-js-button mdl-button--fab mdl-button--mini-fab mdl-button--colored">
+          <i class="material-icons">add</i>
+        </button>
+      </div>
+      <div class="mdl-cell mdl-cell--2-col mdl-cell--middle">
+        <button class="mdl-button mdl-js-button mdl-button--fab mdl-button--mini-fab">
+          <i class="material-icons">add</i>
+        </button>
+      </div>
+      <div class="mdl-cell mdl-cell--2-col mdl-cell--middle">
+        <button class="mdl-button mdl-js-button mdl-button--fab mdl-button--mini-fab" disabled>
+          <i class="material-icons">add</i>
+        </button>
+      </div>
+
+      <div class="mdl-cell mdl-cell--2-col mdl-cell--middle">
+        <button class="mdl-button mdl-js-button mdl-button--raised">
+          Raised
+        </button>
+      </div>
+      <div class="mdl-cell mdl-cell--2-col mdl-cell--middle">
+        <button class="mdl-button mdl-js-button mdl-button--raised" disabled>
+          Disabled
+        </button>
+      </div>
+
+      <div class="mdl-cell mdl-cell--2-col mdl-cell--middle">
+        <button class="mdl-button mdl-js-button mdl-button--raised mdl-button--colored">
+          Colored
+        </button>
+      </div>
+      <div class="mdl-cell mdl-cell--2-col mdl-cell--middle">
+        <button class="mdl-button mdl-js-button mdl-button--raised mdl-button--accent">
+          Accent
+        </button>
+      </div>
+
+      <div class="mdl-cell mdl-cell--2-col mdl-cell--middle">
+        <button class="mdl-button mdl-js-button mdl-button--raised mdl-button--colored mdl-js-ripple-effect">
+          <i class="material-icons">settings</i>&nbsp;Settings
+        </button>
+      </div>
+
+      <div class="mdl-cell mdl-cell--2-col mdl-cell--middle">
+        <button class="mdl-button mdl-js-button mdl-button--raised mdl-button--accent mdl-js-ripple-effect animated bounce">
+          <i class="material-icons">favorite</i>&nbsp;Fav
+        </button>
+      </div>
+
+      <div class="mdl-cell mdl-cell--2-col mdl-cell--middle">
+        <button class="mdl-button mdl-js-button">
+          Flat
+        </button>
+      </div>
+      <div class="mdl-cell mdl-cell--2-col mdl-cell--middle">
+        <button class="mdl-button mdl-js-button" disabled>
+          Disabled
+        </button>
+      </div>
+
+      <div class="mdl-cell mdl-cell--2-col mdl-cell--middle">
+        <button class="mdl-button mdl-js-button mdl-button--primary">
+          Colored
+        </button>
+      </div>
+      <div class="mdl-cell mdl-cell--2-col mdl-cell--middle">
+        <button class="mdl-button mdl-js-button mdl-button--accent">
+          Accent
+        </button>
+      </div>
+
+      <div class="mdl-cell mdl-cell--2-col mdl-cell--middle">
+        <button class="mdl-button mdl-js-button">
+          <i class="material-icons">snooze</i>&nbsp;Ring, ring...
+        </button>
+      </div>
+
+      <div class="mdl-cell mdl-cell--2-col mdl-cell--middle">
+        <button class="mdl-button mdl-js-button mdl-button--icon">
+          <i class="material-icons">mood</i>
+        </button>
+      </div>
+      <div class="mdl-cell mdl-cell--2-col mdl-cell--middle">
+        <button class="mdl-button mdl-js-button mdl-button--icon mdl-button--colored">
+          <i class="material-icons">mood</i>
+        </button>
+      </div>
+      <div class="mdl-cell mdl-cell--2-col mdl-cell--middle">
+        <button class="mdl-button mdl-js-button mdl-button--fab mdl-color--lime mdl-button--accent">
+          <i class="material-icons">cloud</i>
+        </button>
+      </div>
+
+      <div class="mdl-cell mdl-cell--2-col mdl-cell--middle">
+        <button class="mdl-button mdl-js-button mdl-button--raised mdl-color--deep-orange-100 mdl-js-ripple-effect">
+          <i class="material-icons">settings</i>&nbsp;Settings
+        </button>
+      </div>
+    </div>
+  </section>
+
+
+  <!-- Toggles -->
+  <section>
+    <div class="mdl-grid demo-toggle-grid">
+      <div class="mdl-cell mdl-cell--2-col">
+        <label class="mdl-checkbox mdl-js-checkbox mdl-js-ripple-effect">
+          <input type="checkbox" class="mdl-checkbox__input" checked>
+          <span class="mdl-checkbox__label">Checkbox</span>
+        </label>
+      </div>
+      <div class="mdl-cell mdl-cell--2-col">
+        <label class="mdl-checkbox mdl-js-checkbox mdl-js-ripple-effect">
+          <input type="checkbox" class="mdl-checkbox__input">
+          <span class="mdl-checkbox__label">Checkbox</span>
+        </label>
+      </div>
+      <div class="mdl-cell mdl-cell--2-col">
+        <label class="mdl-checkbox mdl-js-checkbox mdl-js-ripple-effect">
+          <input type="checkbox" class="mdl-checkbox__input" checked disabled>
+          <span class="mdl-checkbox__label">Checkbox</span>
+        </label>
+      </div>
+
+      <div class="mdl-cell mdl-cell--2-col">
+        <label class="mdl-radio mdl-js-radio mdl-js-ripple-effect">
+          <input type="radio" class="mdl-radio__button" name="options30" value="1" checked>
+          <span class="mdl-radio__label">First</span>
+        </label>
+      </div>
+      <div class="mdl-cell mdl-cell--2-col">
+        <label class="mdl-radio mdl-js-radio mdl-js-ripple-effect">
+          <input type="radio" class="mdl-radio__button" name="options30" value="2">
+          <span class="mdl-radio__label">Second</span>
+        </label>
+      </div>
+      <div class="mdl-cell mdl-cell--2-col">
+        <label class="mdl-radio mdl-js-radio mdl-js-ripple-effect">
+          <input type="radio" class="mdl-radio__button" name="options30" value="3" disabled>
+          <span class="mdl-radio__label">Third</span>
+        </label>
+      </div>
+
+      <div class="mdl-cell mdl-cell--2-col">
+        <label class="mdl-icon-toggle mdl-js-icon-toggle mdl-js-ripple-effect">
+          <input type="checkbox" class="mdl-icon-toggle__input" checked>
+          <i class="mdl-icon-toggle__label material-icons">format_bold</i>
+        </label>
+      </div>
+      <div class="mdl-cell mdl-cell--2-col">
+        <label class="mdl-icon-toggle mdl-js-icon-toggle mdl-js-ripple-effect">
+          <input type="checkbox" class="mdl-icon-toggle__input">
+          <i class="mdl-icon-toggle__label material-icons">format_italic</i>
+        </label>
+      </div>
+      <div class="mdl-cell mdl-cell--2-col">
+        <label class="mdl-icon-toggle mdl-js-icon-toggle mdl-js-ripple-effect">
+          <input type="checkbox" class="mdl-icon-toggle__input" disabled>
+          <i class="mdl-icon-toggle__label material-icons">format_italic</i>
+        </label>
+      </div>
+
+      <div class="mdl-cell mdl-cell--2-col">
+        <label class="mdl-switch mdl-js-switch mdl-js-ripple-effect">
+          <input type="checkbox" class="mdl-switch__input" checked>
+          <span class="mdl-switch__label"></span>
+        </label>
+      </div>
+      <div class="mdl-cell mdl-cell--2-col">
+        <label class="mdl-switch mdl-js-switch mdl-js-ripple-effect">
+          <input type="checkbox" class="mdl-switch__input">
+          <span class="mdl-switch__label"></span>
+        </label>
+      </div>
+      <div class="mdl-cell mdl-cell--2-col">
+        <label class="mdl-switch mdl-js-switch mdl-js-ripple-effect">
+          <input type="checkbox" class="mdl-switch__input" disabled>
+          <span class="mdl-switch__label"></span>
+        </label>
+      </div>
+    </div>
+  </section>
+
+
+  <!-- Sliders -->
+  <section>
+    <div class="mdl-grid demo-slider-grid">
+      <div class="mdl-cell mdl-cell--4-col mdl-cell--2-col-phone">
+        <!-- Default Slider -->
+        <input class="mdl-slider mdl-js-slider" type="range" min="0" max="100" value="0">
+      </div>
+
+      <div class="mdl-cell mdl-cell--4-col mdl-cell--2-col-phone">
+        <!-- Slider with Starting Value -->
+        <input class="mdl-slider mdl-js-slider" type="range" min="0" max="100" value="25">
+      </div>
+    </div>
+  </section>
+
+
+  <!-- Data table -->
+  <section>
+    <table class="mdl-data-table mdl-js-data-table mdl-data-table--selectable mdl-shadow--2dp">
+      <thead>
+      <tr>
+        <th class="mdl-data-table__cell--non-numeric">Materials</th>
+        <th>Quantity</th>
+        <th>Unit price</th>
+      </tr>
+      </thead>
+      <tbody>
+      <tr>
+        <td class="mdl-data-table__cell--non-numeric">Acrylic (Transparent)</td>
+        <td>25</td>
+        <td>$2.90</td>
+      </tr>
+      <tr>
+        <td class="mdl-data-table__cell--non-numeric">Plywood (Birch)</td>
+        <td>50</td>
+        <td>$1.25</td>
+      </tr>
+      <tr>
+        <td class="mdl-data-table__cell--non-numeric">Laminate (Gold on Blue)</td>
+        <td>10</td>
+        <td>$2.35</td>
+      </tr>
+      </tbody>
+    </table>
+  </section>
+
+
+  <!-- Menu -->
+  <!--
+  <section>
+    <div class="demo-menu demo-menu__lower-left">
+      <div class="demo-menu-container mdl-shadow--2dp mdl-color--primary-dark mdl-color-text--primary-contrast">
+        <div class="demo-menu-bar">
+          <button id="demo-menu-lower-left-30" class="mdl-button mdl-js-button mdl-button--icon">
+            <i class="material-icons">more_vert</i>
+          </button>
+          <ul class="mdl-menu mdl-menu--bottom-left mdl-js-menu mdl-js-ripple-effect" for="demo-menu-lower-left-30">
+            <li class="mdl-menu__item">Some Action</li>
+            <li class="mdl-menu__item">Another Action</li>
+            <li disabled class="mdl-menu__item">Disabled Action</li>
+            <li class="mdl-menu__item">Yet Another Action</li>
+          </ul>
+
+          <span>Menu lower left</span>
+
+        </div>
+        <div class="demo-menu-background-light"></div>
+      </div>
+    </div>
+  </section>
+  -->
+
+  <!-- Menu button -->
+  <section style="padding-bottom:16px">
+    <h4>Menu button</h4>
+
+    <button class="mdl-button mdl-button--raised mdl-js-ripple-effect mdl-js-button mdlext-js-menu-button">
+      <i class="material-icons">gesture</i>
+      <span class="mdlext-menu-button__caption">Select</span>
+      <i class="material-icons mdlext-aria-expanded-more-less"></i>
+    </button>
+    <ul class="mdlext-menu mdlext-light-color-theme" hidden >
+      <li class="mdlext-menu__item">
+        <i class="material-icons md-18">info</i>
+        <span class="mdlext-menu__item__caption">Menu item #1</span>
+      </li>
+      <li class="mdlext-menu__item">
+        <i class="material-icons md-18">help_outline</i>
+        <span class="mdlext-menu__item__caption">Menu item #2. A long text to check ellipsis overflow 0123456789</span>
+        <i class="material-icons md-18">radio</i>
+      </li>
+      <li class="mdlext-menu__item-separator"></li>
+      <li class="mdlext-menu__item" disabled>
+        <span class="mdlext-menu__item__caption">Menu item #3, disabled</span>
+        <i class="material-icons md-18">accessibility</i>
+      </li>
+      <li class="mdlext-menu__item-separator"></li>
+      <li class="mdlext-menu__item">
+        <span class="mdlext-menu__item__caption">Menu item #IV</span>
+        <i class="material-icons md-18">build</i>
+      </li>
+      <li class="mdlext-menu__item">
+        <span class="mdlext-menu__item__caption">Menu item #V</span>
+        <i class="material-icons md-18">build</i>
+      </li>
+      <li class="mdlext-menu__item-separator"></li>
+      <li class="mdlext-menu__item">
+        <span class="mdlext-menu__item__caption">Menu item #VI</span>
+        <i class="material-icons md-18">build</i>
+      </li>
+      <li class="mdlext-menu__item">
+        <span class="mdlext-menu__item__caption">Menu item #VII</span>
+        <i class="material-icons md-18">build</i>
+      </li>
+      <li class="mdlext-menu__item">
+        Menu item #n
+      </li>
+    </ul>
+  </section>
+
+</div>
+
+
+
+<!-- Dark theme -->
+<h2>Dark Color Theme</h2>
+
+
+<div class="demo-theme-container mdlext-dark-color-theme">
+
+  <section>
+    <table class="info">
+      <tr>
+        <th class="mdl-typography--caption-color-contrast">.mdl-typography--</th>
+        <td class="mdl-typography--title">Scale &amp; Basic Styles</td>
+      </tr>
+      <tr>
+        <th class="mdl-typography--caption-color-contrast">display-4</th>
+        <td class="mdl-typography--display-4">Light 112px</td>
+      </tr>
+      <tr>
+        <th class="mdl-typography--caption-color-contrast">display-3</th>
+        <td class="mdl-typography--display-3">Regular 56px</td>
+      </tr>
+      <tr>
+        <th class="mdl-typography--caption-color-contrast">display-2</th>
+        <td class="mdl-typography--display-2">Regular 45px</td>
+      </tr>
+      <tr>
+        <th class="mdl-typography--caption-color-contrast">display-1</th>
+        <td class="mdl-typography--display-1">Regular 34px</td>
+      </tr>
+      <tr>
+        <th class="mdl-typography--caption-color-contrast">headline</th>
+        <td class="mdl-typography--headline">Regular 24px</td>
+      </tr>
+      <tr>
+        <th class="mdl-typography--caption-color-contrast">title</th>
+        <td class="mdl-typography--title">Medium 20px</td>
+      </tr>
+      <tr>
+        <th class="mdl-typography--caption-color-contrast">subhead</th>
+        <td class="mdl-typography--subhead">Regular 16px (Device), Regular 15px (Desktop)</td>
+      </tr>
+      <tr>
+        <th class="mdl-typography--caption-color-contrast">body-2</th>
+        <td class="mdl-typography--body-2">Medium 14px (Device), Medium 13px (Desktop)</td>
+      </tr>
+      <tr>
+        <th class="mdl-typography--caption-color-contrast">body-1</th>
+        <td class="mdl-typography--body-1">Regular 14px (Device), Regular 13px (Desktop)</td>
+      </tr>
+      <tr>
+        <th class="mdl-typography--caption-color-contrast">body-2-force-preferred-font</th>
+        <td class="mdl-typography--body-2-force-preferred-font">Medium 14px (Device), Medium 13px (Desktop)</td>
+      </tr>
+      <tr>
+        <th class="mdl-typography--caption-color-contrast">body-1-force-preferred-font</th>
+        <td class="mdl-typography--body-1-force-preferred-font">Regular 14px (Device), Regular 13px (Desktop)</td>
+      </tr>
+      <tr>
+        <th class="mdl-typography--caption-color-contrast">caption</th>
+        <td class="mdl-typography--caption">Regular 12px</td>
+      </tr>
+      <tr>
+        <th class="mdl-typography--caption-color-contrast">menu</th>
+        <td class="mdl-typography--menu">Medium 14px (Device), Medium 13px (Desktop)</td>
+      </tr>
+      <tr>
+        <th class="mdl-typography--caption-color-contrast">button</th>
+        <td class="mdl-typography--button">Medium (All Caps) 14px</td>
+      </tr>
+
+      <tr>
+        <th class="mdl-typography--caption-color-contrast">primary-dark</th>
+        <td class="mdl-color--primary-dark mdl-color-text--primary-contrast">mdl-color--primary-dark mdl-color-text--primary-contrast</td>
+      </tr>
+      <tr>
+        <th class="mdl-typography--caption-color-contrast">primary</th>
+        <td class="mdl-color--primary mdl-color-text--primary-contrast">mdl-color--primary mdl-color-text--primary-contrast</td>
+      </tr>
+      <tr>
+        <th class="mdl-typography--caption-color-contrast">accent</th>
+        <td class="mdl-color--accent mdl-color-text--accent-contrast">mdl-color--accent mdl-color-text--accent-contrast</td>
+      </tr>
+      <tr>
+        <th class="mdl-typography--caption-color-contrast">primary-dark</th>
+        <td class="mdl-color--primary-contrast mdl-color-text--primary-dark">mdl-color--primary-contrast mdl-color-text--primary-dark</td>
+      </tr>
+      <tr>
+        <th class="mdl-typography--caption-color-contrast">primary</th>
+        <td class="mdl-color--primary-contrast mdl-color-text--primary">mdl-color-text--primary</td>
+      </tr>
+      <tr>
+        <th class="mdl-typography--caption-color-contrast">accent</th>
+        <td class="mdl-color--accent-contrast mdl-color-text--accent">mdl-color--accent-contrast mdl-color-text--accent</td>
+      </tr>
+    </table>
+  </section>
+
+  <section>
+    <h1>Base font</h1>
+
+    <p>Material Design Lite start’s with a base font of</p>
+    <ul>
+      <li>A size of 14px</li>
+      <li>A weight of 400</li>
+      <li>A line height of 20px</li>
+    </ul>
+
+    <p class="mdl-typography--body-1">Regular 14px (Device), Regular 13px (Desktop)</p>
+    <p class="mdl-typography--body-1-force-preferred-font">Regular 14px (Device), Regular 13px (Desktop)</p>
+    <p class="mdl-typography--body-2">Medium 14px (Device), Medium 13px (Desktop)</p>
+    <p class="mdl-typography--body-2-color-contrast">Body with color contrast</p>
+    <p class="mdl-typography--body-2-force-preferred-font">Medium 14px (Device), Medium 13px (Desktop)</p>
+    <p><a href="#" onclick="return false">An anchor</a></p>
+
+    <h1>Headings</h1>
+    <h1>h1 (56px) <small>Subtitle</small></h1>
+    <h2>h2 (45px) <small>Subtitle</small></h2>
+    <h3>h3 (34px) <small>Subtitle</small></h3>
+    <h4>h4 (24px) <small>Subtitle</small></h4>
+    <h5>h5 (20px) <small>Subtitle</small></h5>
+    <h6>h6 (16px) <small>Subtitle</small></h6>
+  </section>
+
+
+  <!-- textfields -->
+  <section class = "textfield-demo-container">
+
+    <div class="mdl-grid mdl-grid--no-spacing">
+
+      <div class="mdl-cell mdl-cell--4-col">
+        <div class="mdl-textfield mdl-js-textfield">
+          <input class="mdl-textfield__input" type="text">
+          <label class="mdl-textfield__label">Text...</label>
+        </div>
+      </div>
+
+      <div class="mdl-cell mdl-cell--4-col">
+        <div class="mdl-textfield mdl-js-textfield">
+          <input class="mdl-textfield__input" type="text" pattern="-?[0-9]*(\.[0-9]+)?">
+          <label class="mdl-textfield__label">Number...</label>
+          <span class="mdl-textfield__error">Input is not a number!</span>
+        </div>
+      </div>
+
+      <div class="mdl-cell mdl-cell--4-col">
+        <div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label">
+          <input class="mdl-textfield__input" type="text" list="languages" placeholder="Select a programming language" required>
+          <label class="mdl-textfield__label">Programming Language</label>
+        </div>
+      </div>
+
+      <div class="mdl-cell mdl-cell--4-col">
+        <div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label">
+          <input class="mdl-textfield__input" type="text" pattern="-?[0-9]*(\.[0-9]+)?">
+          <label class="mdl-textfield__label">Number...</label>
+          <span class="mdl-textfield__error">Input is not a number!</span>
+        </div>
+      </div>
+
+      <div class="mdl-cell mdl-cell--4-col">
+        <div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label">
+          <input class="mdl-textfield__input" type="text" pattern="-?[0-9]*(\.[0-9]+)?" disabled value="123">
+          <label class="mdl-textfield__label">Number...</label>
+          <span class="mdl-textfield__error">Input is not a number!</span>
+        </div>
+      </div>
+
+      <div class="mdl-cell mdl-cell--4-col">
+        <div class="mdl-textfield mdl-js-textfield mdl-textfield--expandable mdl-textfield--floating-label">
+          <label class="mdl-button mdl-js-button mdl-button--icon" for="mdl-expandable-demo2">
+            <i class="material-icons">search</i>
+          </label>
+          <div class="mdl-textfield__expandable-holder">
+            <input class="mdl-textfield__input" type="text" name="q" value="" id="mdl-expandable-demo2" pattern=".{3,}" />
+            <label class="mdl-textfield__label" for="mdl-expandable-demo2">Expandable Input</label>
+          </div>
+        </div>
+      </div>
+
+      <div class="mdl-cell mdl-cell--8-col">
+        <div class="mdl-textfield mdl-js-textfield mdl-textfield--full-width mdl-textfield--floating-label">
+          <textarea class="mdl-textfield__input" rows= "3" ></textarea>
+          <label class="mdl-textfield__label">Text lines...</label>
+        </div>
+      </div>
+
+    </div>
+
+  </section>
+
+
+
+  <!-- Selectfield -->
+  <section style="margin-bottom: 16px;">
+    <div class="mdl-grid mdl-grid--no-spacing">
+
+      <div class="mdl-cell mdl-cell--4-col">
+        <div class="mdlext-selectfield mdlext-js-selectfield">
+          <select class="mdlext-selectfield__select" name="mdl-professsion3">
+            <option value=""></option>
+            <option value="option1">option 1</option>
+            <option value="option2">option 2</option>
+            <option value="option3">option 3</option>
+            <option value="option4">option 4</option>
+            <option value="option5">option 5</option>
+          </select>
+          <label class="mdlext-selectfield__label">Profession</label>
+        </div>
+      </div>
+
+      <div class="mdl-cell mdl-cell--4-col">
+        <div class="mdlext-selectfield mdlext-js-selectfield mdlext-selectfield--floating-label">
+          <select class="mdlext-selectfield__select" name="mdl-professsion20">
+            <option value=""></option>
+            <option value="option1">option 1</option>
+            <option value="option2">option 2</option>
+            <option value="option3">option 3</option>
+            <option value="option4">option 4</option>
+            <option value="option5">option 5</option>
+          </select>
+          <label class="mdlext-selectfield__label">Profession</label>
+        </div>
+      </div>
+
+      <div class="mdl-cell mdl-cell--4-col">
+        <div class="mdlext-selectfield mdlext-js-selectfield mdlext-selectfield--floating-label">
+          <select class="mdlext-selectfield__select" name="mdl-professsion22" disabled>
+            <option value=""></option>
+            <option value="option1">option 1</option>
+            <option value="option2">option 2</option>
+            <option value="option3">option 3</option>
+            <option value="option4">option 4</option>
+            <option value="option5">option 5</option>
+          </select>
+          <label class="mdlext-selectfield__label">Profession</label>
+        </div>
+      </div>
+    </div>
+  </section>
+
+
+
+  <!-- bordered fields -->
+  <section class="mdlext-bordered-fields" style="margin-top:16px;">
+
+    <div class="mdl-grid mdl-grid--no-spacing">
+
+      <div class="mdl-cell mdl-cell--4-col">
+        <div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label">
+          <input class="mdl-textfield__input" type="text" list="languages" placeholder="Select a language" required>
+          <label class="mdl-textfield__label">Programming language</label>
+        </div>
+      </div>
+
+      <div class="mdl-cell mdl-cell--4-col">
+        <div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label">
+          <input class="mdl-textfield__input" type="text" pattern="-?[0-9]*(\.[0-9]+)?">
+          <label class="mdl-textfield__label">Numeric with floating label</label>
+          <span class="mdl-textfield__error">Input is not a number!</span>
+        </div>
+      </div>
+
+      <div class="mdl-cell mdl-cell--4-col">
+        <div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label">
+          <input class="mdl-textfield__input" type="text" pattern="-?[0-9]*(\.[0-9]+)?" disabled value="123">
+          <label class="mdl-textfield__label" >Disabled floating label</label>
+          <span class="mdl-textfield__error">Input is not a number!</span>
+        </div>
+      </div>
+
+      <div class="mdl-cell mdl-cell--4-col">
+        <div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label mdlext-bordered-fields__icon-right ">
+          <input class="mdl-textfield__input" type="text" id="uploadfile22" readonly>
+          <label class="mdl-textfield__label">File (work in progress)</label>
+
+          <label class="mdl-button mdl-js-button mdl-button--primary mdl-button--icon mdl-button--file" for="uploadfile22">
+            <i class="material-icons">attach_file</i>
+            <input type="file" id="uploadBtn22">
+          </label>
+        </div>
+        <!--
+          // Need a script to work properly - something like this
+        -->
+        <script>
+          (function() {
+            'use strict';
+            document.querySelector('#uploadBtn22').addEventListener('change', function() {
+              var n = document.querySelector("#uploadfile22");
+              n.value = this.files[0].name;
+              n.parentNode.classList.add('is-dirty');
+            });
+          }());
+        </script>
+      </div>
+
+      <div class="mdl-cell mdl-cell--4-col">
+        <div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label mdlext-bordered-fields__icon-left mdlext-bordered-fields__icon-right">
+          <i class="material-icons">radio</i>
+          <input class="mdl-textfield__input" type="text" disabled>
+          <label class="mdl-textfield__label">Text, disabled</label>
+          <i class="material-icons">fingerprint</i>
+        </div>
+      </div>
+
+
+      <div class="mdl-cell mdl-cell--4-col">
+        <div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label mdlext-bordered-fields__icon-left">
+          <label class="mdl-button mdl-js-button mdl-button--icon">
+            <i class="material-icons">phone</i>
+          </label>
+
+          <input class="mdl-textfield__input" type="text">
+          <label class="mdl-textfield__label">Text...</label>
+        </div>
+      </div>
+
+      <div class="mdl-cell mdl-cell--4-col">
+        <div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label mdlext-bordered-fields__icon-right">
+          <input class="mdl-textfield__input" type="text">
+          <label class="mdl-textfield__label">Text...</label>
+
+          <label class="mdl-button mdl-js-button mdl-button--icon">
+            <i class="material-icons">settings_voice</i>
+          </label>
+        </div>
+      </div>
+
+
+      <div class="mdl-cell mdl-cell--4-col">
+        <div class="mdlext-selectfield mdlext-js-selectfield mdlext-selectfield--floating-label">
+          <select class="mdlext-selectfield__select">
+            <option value=""></option>
+            <option value="option1">option 1</option>
+            <option value="option2">option 2</option>
+            <option value="option3">option 3</option>
+            <option value="option4">option 4</option>
+            <option value="option5">option 5</option>
+          </select>
+          <label class="mdlext-selectfield__label">Profession</label>
+        </div>
+      </div>
+
+      <div class="mdl-cell mdl-cell--4-col">
+        <div class="mdlext-selectfield mdlext-js-selectfield mdlext-selectfield--floating-label">
+          <select class="mdlext-selectfield__select" disabled>
+            <option value=""></option>
+            <option value="option1">option 1</option>
+            <option value="option2">option 2</option>
+            <option value="option3">option 3</option>
+            <option value="option4">option 4</option>
+            <option value="option5">option 5</option>
+          </select>
+          <label class="mdlext-selectfield__label">Profession</label>
+        </div>
+      </div>
+
+      <div class="mdl-cell mdl-cell--4-col">
+        <div class="mdlext-selectfield mdlext-js-selectfield mdlext-selectfield--floating-label mdlext-bordered-fields__icon-left">
+          <label class="mdl-button mdl-js-button mdl-button--icon">
+            <i class="material-icons">phone</i>
+          </label>
+          <select class="mdlext-selectfield__select">
+            <option value=""></option>
+            <option value="option1">option 1</option>
+            <option value="option2">option 2</option>
+            <option value="option3">option 3</option>
+            <option value="option4">option 4</option>
+            <option value="option5">option 5</option>
+          </select>
+          <label class="mdlext-selectfield__label">Profession</label>
+        </div>
+      </div>
+
+      <div class="mdl-cell mdl-cell--4-col">
+        <div class="mdlext-selectfield mdlext-js-selectfield mdlext-selectfield--floating-label mdlext-bordered-fields__icon-left">
+          <label class="mdl-button mdl-js-button mdl-button--icon">
+            <i class="material-icons">phone</i>
+          </label>
+          <select class="mdlext-selectfield__select" disabled>
+            <option value=""></option>
+            <option value="option1">option 1</option>
+            <option value="option2">option 2</option>
+            <option value="option3">option 3</option>
+            <option value="option4">option 4</option>
+            <option value="option5">option 5</option>
+          </select>
+          <label class="mdlext-selectfield__label">Profession</label>
+        </div>
+      </div>
+
+
+
+      <div class="mdl-cell mdl-cell--4-col">
+        <div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label mdlext-bordered-fields__icon-left">
+          <i class="material-icons">radio</i>
+          <input class="mdl-textfield__input" type="text">
+          <label class="mdl-textfield__label">Text...</label>
+        </div>
+      </div>
+
+      <div class="mdl-cell mdl-cell--4-col">
+        <div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label mdlext-bordered-fields__icon-right">
+          <input class="mdl-textfield__input" type="text">
+          <label class="mdl-textfield__label">Text...</label>
+          <i class="material-icons">fingerprint</i>
+        </div>
+      </div>
+
+      <div class="mdl-cell mdl-cell--4-col">
+        <div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label mdlext-bordered-fields__icon-left mdlext-bordered-fields__icon-right">
+          <i class="material-icons">radio</i>
+          <input class="mdl-textfield__input" type="text">
+          <label class="mdl-textfield__label">Text...</label>
+          <i class="material-icons">fingerprint</i>
+        </div>
+      </div>
+
+      <div class="mdl-cell mdl-cell--4-col">
+        <div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label mdlext-bordered-fields__icon-left mdlext-bordered-fields__icon-right">
+          <label class="mdl-button mdl-js-button mdl-button--icon">
+            <i class="material-icons">phone</i>
+          </label>
+
+          <input class="mdl-textfield__input" type="text">
+          <label class="mdl-textfield__label">Text...</label>
+
+          <label class="mdl-button mdl-js-button mdl-button--icon">
+            <i class="material-icons">settings_voice</i>
+          </label>
+        </div>
+      </div>
+
+      <div class="mdl-cell mdl-cell--4-col">
+        <div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label mdlext-bordered-fields__icon-left mdlext-bordered-fields__icon-right">
+          <label class="mdl-button mdl-js-button mdl-button--icon">
+            <i class="material-icons">phone</i>
+          </label>
+
+          <input class="mdl-textfield__input" type="text" disabled>
+          <label class="mdl-textfield__label">Text...</label>
+
+          <label class="mdl-button mdl-js-button mdl-button--icon">
+            <i class="material-icons">settings_voice</i>
+          </label>
+        </div>
+      </div>
+
+      <div class="mdl-cell mdl-cell--4-col">
+        <div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label mdlext-bordered-fields__icon-left mdlext-bordered-fields__icon-right">
+          <i class="material-icons">radio</i>
+          <input class="mdl-textfield__input" type="text">
+          <label class="mdl-textfield__label">Text...</label>
+          <label class="mdl-button mdl-js-button mdl-button--icon">
+            <i class="material-icons">settings_voice</i>
+          </label>
+        </div>
+      </div>
+
+    </div>
+
+    <fieldset disabled>
+      <legend>Disabled fieldset</legend>
+      <div class="mdlext-selectfield mdlext-js-selectfield mdlext-selectfield--floating-label">
+        <select class="mdlext-selectfield__select">
+          <option value=""></option>
+          <option value="option1">option 1</option>
+          <option value="option2">option 2</option>
+          <option value="option3">option 3</option>
+          <option value="option4">option 4</option>
+          <option value="option5">option 5</option>
+          <option value="option6">option 5 abcdefghijklmnopqrstuvw0123456789</option>
+        </select>
+        <label class="mdlext-selectfield__label">Profession</label>
+      </div>
+
+      <div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label">
+        <input class="mdl-textfield__input" type="text" pattern="-?[0-9]*(\.[0-9]+)?">
+        <label class="mdl-textfield__label">Number...</label>
+        <span class="mdl-textfield__error">Input is not a number!</span>
+      </div>
+
+      <div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label mdlext-bordered-fields__icon-left mdlext-bordered-fields__icon-right">
+        <i class="material-icons">radio</i>
+        <input class="mdl-textfield__input" type="text">
+        <label class="mdl-textfield__label">Text...</label>
+        <label class="mdl-button mdl-js-button mdl-button--icon">
+          <i class="material-icons">settings_voice</i>
+        </label>
+      </div>
+    </fieldset>
+
+  </section>
+
+
+  <!-- Badges -->
+  <section style="margin-top:16px">
+    <div class="mdl-grid demo-badge-grid">
+      <div class="mdl-cell mdl-cell--2-col">
+        <span class="mdl-badge" data-badge="4">Inbox</span>
+      </div>
+      <div class="mdl-cell mdl-cell--2-col">
+        <span class="material-icons mdl-badge" data-badge="1">account_box</span>
+      </div>
+      <div class="mdl-cell mdl-cell--2-col">
+        <span class="mdl-badge" data-badge="♥">Mood</span>
+      </div>
+      <div class="mdl-cell mdl-cell--2-col">
+        <span class="material-icons mdl-badge" data-badge="♥">account_box</span>
+      </div>
+      <div class="mdl-cell mdl-cell--2-col">
+        <a href="#" onclick="return false" class="mdl-badge" data-badge="5">Inbox</a>
+      </div>
+    </div>
+
+  </section>
+
+
+  <!-- Buttons -->
+  <section>
+    <div class="mdl-grid demo-button-grid">
+      <div class="mdl-cell mdl-cell--2-col mdl-cell--middle">
+        <button class="mdl-button mdl-js-button mdl-button--fab mdl-button--colored">
+          <i class="material-icons">add</i>
+        </button>
+      </div>
+      <div class="mdl-cell mdl-cell--2-col mdl-cell--middle">
+        <button class="mdl-button mdl-js-button mdl-button--fab">
+          <i class="material-icons">add</i>
+        </button>
+      </div>
+      <div class="mdl-cell mdl-cell--2-col mdl-cell--middle">
+        <button class="mdl-button mdl-js-button mdl-button--fab" disabled>
+          <i class="material-icons">add</i>
+        </button>
+      </div>
+
+      <div class="mdl-cell mdl-cell--2-col mdl-cell--middle">
+        <button class="mdl-button mdl-js-button mdl-button--fab mdl-button--mini-fab mdl-button--colored">
+          <i class="material-icons">add</i>
+        </button>
+      </div>
+      <div class="mdl-cell mdl-cell--2-col mdl-cell--middle">
+        <button class="mdl-button mdl-js-button mdl-button--fab mdl-button--mini-fab">
+          <i class="material-icons">add</i>
+        </button>
+      </div>
+      <div class="mdl-cell mdl-cell--2-col mdl-cell--middle">
+        <button class="mdl-button mdl-js-button mdl-button--fab mdl-button--mini-fab" disabled>
+          <i class="material-icons">add</i>
+        </button>
+      </div>
+
+      <div class="mdl-cell mdl-cell--2-col mdl-cell--middle">
+        <button class="mdl-button mdl-js-button mdl-button--raised">
+          Raised
+        </button>
+      </div>
+      <div class="mdl-cell mdl-cell--2-col mdl-cell--middle">
+        <button class="mdl-button mdl-js-button mdl-button--raised" disabled>
+          Disabled
+        </button>
+      </div>
+
+      <div class="mdl-cell mdl-cell--2-col mdl-cell--middle">
+        <button class="mdl-button mdl-js-button mdl-button--raised mdl-button--colored">
+          Colored
+        </button>
+      </div>
+      <div class="mdl-cell mdl-cell--2-col mdl-cell--middle">
+        <button class="mdl-button mdl-js-button mdl-button--raised mdl-button--accent">
+          Accent
+        </button>
+      </div>
+
+      <div class="mdl-cell mdl-cell--2-col mdl-cell--middle">
+        <button class="mdl-button mdl-js-button mdl-button--raised mdl-button--colored mdl-js-ripple-effect">
+          <i class="material-icons">settings</i>&nbsp;Settings
+        </button>
+      </div>
+
+      <div class="mdl-cell mdl-cell--2-col mdl-cell--middle">
+        <button class="mdl-button mdl-js-button mdl-button--raised mdl-button--accent mdl-js-ripple-effect animated bounce">
+          <i class="material-icons">favorite</i>&nbsp;Fav
+        </button>
+      </div>
+
+      <div class="mdl-cell mdl-cell--2-col mdl-cell--middle">
+        <button class="mdl-button mdl-js-button">
+          Flat
+        </button>
+      </div>
+      <div class="mdl-cell mdl-cell--2-col mdl-cell--middle">
+        <button class="mdl-button mdl-js-button" disabled>
+          Disabled
+        </button>
+      </div>
+
+      <div class="mdl-cell mdl-cell--2-col mdl-cell--middle">
+        <button class="mdl-button mdl-js-button mdl-button--primary">
+          Colored
+        </button>
+      </div>
+      <div class="mdl-cell mdl-cell--2-col mdl-cell--middle">
+        <button class="mdl-button mdl-js-button mdl-button--accent">
+          Accent
+        </button>
+      </div>
+
+      <div class="mdl-cell mdl-cell--2-col mdl-cell--middle">
+        <button class="mdl-button mdl-js-button">
+          <i class="material-icons">snooze</i>&nbsp;Ring, ring...
+        </button>
+      </div>
+
+      <div class="mdl-cell mdl-cell--2-col mdl-cell--middle">
+        <button class="mdl-button mdl-js-button mdl-button--icon">
+          <i class="material-icons">mood</i>
+        </button>
+      </div>
+      <div class="mdl-cell mdl-cell--2-col mdl-cell--middle">
+        <button class="mdl-button mdl-js-button mdl-button--icon mdl-button--colored">
+          <i class="material-icons">mood</i>
+        </button>
+      </div>
+      <div class="mdl-cell mdl-cell--2-col mdl-cell--middle">
+        <button class="mdl-button mdl-js-button mdl-button--fab mdl-color--lime mdl-button--accent">
+          <i class="material-icons">cloud</i>
+        </button>
+      </div>
+
+      <div class="mdl-cell mdl-cell--2-col mdl-cell--middle">
+        <button class="mdl-button mdl-js-button mdl-button--raised mdl-color--deep-orange-100 mdl-js-ripple-effect">
+          <i class="material-icons">settings</i>&nbsp;Settings
+        </button>
+      </div>
+    </div>
+  </section>
+
+  <!-- Toggles -->
+  <section>
+    <div class="mdl-grid demo-toggle-grid">
+      <div class="mdl-cell mdl-cell--2-col">
+        <label class="mdl-checkbox mdl-js-checkbox mdl-js-ripple-effect">
+          <input type="checkbox" class="mdl-checkbox__input" checked>
+          <span class="mdl-checkbox__label">Checkbox</span>
+        </label>
+      </div>
+      <div class="mdl-cell mdl-cell--2-col">
+        <label class="mdl-checkbox mdl-js-checkbox mdl-js-ripple-effect">
+          <input type="checkbox" class="mdl-checkbox__input">
+          <span class="mdl-checkbox__label">Checkbox</span>
+        </label>
+      </div>
+      <div class="mdl-cell mdl-cell--2-col">
+        <label class="mdl-checkbox mdl-js-checkbox mdl-js-ripple-effect">
+          <input type="checkbox" class="mdl-checkbox__input" checked disabled>
+          <span class="mdl-checkbox__label">Checkbox</span>
+        </label>
+      </div>
+
+      <div class="mdl-cell mdl-cell--2-col">
+        <label class="mdl-radio mdl-js-radio mdl-js-ripple-effect">
+          <input type="radio" class="mdl-radio__button" name="options2" value="1" checked>
+          <span class="mdl-radio__label">First</span>
+        </label>
+      </div>
+      <div class="mdl-cell mdl-cell--2-col">
+        <label class="mdl-radio mdl-js-radio mdl-js-ripple-effect">
+          <input type="radio" class="mdl-radio__button" name="options2" value="2">
+          <span class="mdl-radio__label">Second</span>
+        </label>
+      </div>
+      <div class="mdl-cell mdl-cell--2-col">
+        <label class="mdl-radio mdl-js-radio mdl-js-ripple-effect">
+          <input type="radio" class="mdl-radio__button" name="options2" value="3" disabled>
+          <span class="mdl-radio__label">Third</span>
+        </label>
+      </div>
+
+      <div class="mdl-cell mdl-cell--2-col">
+        <label class="mdl-icon-toggle mdl-js-icon-toggle mdl-js-ripple-effect">
+          <input type="checkbox" class="mdl-icon-toggle__input" checked>
+          <i class="mdl-icon-toggle__label material-icons">format_bold</i>
+        </label>
+      </div>
+      <div class="mdl-cell mdl-cell--2-col">
+        <label class="mdl-icon-toggle mdl-js-icon-toggle mdl-js-ripple-effect">
+          <input type="checkbox" class="mdl-icon-toggle__input">
+          <i class="mdl-icon-toggle__label material-icons">format_italic</i>
+        </label>
+      </div>
+      <div class="mdl-cell mdl-cell--2-col">
+        <label class="mdl-icon-toggle mdl-js-icon-toggle mdl-js-ripple-effect">
+          <input type="checkbox" class="mdl-icon-toggle__input" disabled>
+          <i class="mdl-icon-toggle__label material-icons">format_italic</i>
+        </label>
+      </div>
+
+      <div class="mdl-cell mdl-cell--2-col">
+        <label class="mdl-switch mdl-js-switch mdl-js-ripple-effect">
+          <input type="checkbox" class="mdl-switch__input" checked>
+          <span class="mdl-switch__label"></span>
+        </label>
+      </div>
+      <div class="mdl-cell mdl-cell--2-col">
+        <label class="mdl-switch mdl-js-switch mdl-js-ripple-effect">
+          <input type="checkbox" class="mdl-switch__input">
+          <span class="mdl-switch__label"></span>
+        </label>
+      </div>
+      <div class="mdl-cell mdl-cell--2-col">
+        <label class="mdl-switch mdl-js-switch mdl-js-ripple-effect">
+          <input type="checkbox" class="mdl-switch__input" disabled>
+          <span class="mdl-switch__label"></span>
+        </label>
+      </div>
+    </div>
+  </section>
+
+
+
+  <!-- Sliders -->
+  <section>
+    <div class="mdl-grid demo-slider-grid">
+      <div class="mdl-cell mdl-cell--4-col mdl-cell--2-col-phone">
+        <!-- Default Slider -->
+        <input class="mdl-slider mdl-js-slider" type="range" min="0" max="100" value="0">
+      </div>
+
+      <div class="mdl-cell mdl-cell--4-col mdl-cell--2-col-phone">
+        <!-- Slider with Starting Value -->
+        <input class="mdl-slider mdl-js-slider" type="range" min="0" max="100" value="25">
+      </div>
+    </div>
+  </section>
+
+
+  <!-- Data table -->
+  <section>
+    <table class="mdl-data-table mdl-js-data-table mdl-data-table--selectable mdl-shadow--2dp">
+      <thead>
+      <tr>
+        <th class="mdl-data-table__cell--non-numeric">Materials</th>
+        <th>Quantity</th>
+        <th>Unit price</th>
+      </tr>
+      </thead>
+      <tbody>
+      <tr>
+        <td class="mdl-data-table__cell--non-numeric">Acrylic (Transparent)</td>
+        <td>25</td>
+        <td>$2.90</td>
+      </tr>
+      <tr>
+        <td class="mdl-data-table__cell--non-numeric">Plywood (Birch)</td>
+        <td>50</td>
+        <td>$1.25</td>
+      </tr>
+      <tr>
+        <td class="mdl-data-table__cell--non-numeric">Laminate (Gold on Blue)</td>
+        <td>10</td>
+        <td>$2.35</td>
+      </tr>
+      </tbody>
+    </table>
+  </section>
+
+
+  <!-- Menu -->
+  <!--
+  <section>
+    <div class="demo-menu">
+      <div class="demo-menu-container mdl-shadow--2dp mdl-color--primary-dark mdl-color-text--primary-contrast">
+        <div class="demo-menu-background-dark"></div>
+        <div class="demo-menu-bar">
+          <button id="demo-menu-top-left" class="mdl-button mdl-js-button mdl-button--icon">
+            <i class="material-icons">more_vert</i>
+          </button>
+
+          <ul class="mdl-menu mdl-menu--top-left mdl-js-menu mdl-js-ripple-effect"
+              for="demo-menu-top-left">
+            <li class="mdl-menu__item">Some Action</li>
+            <li class="mdl-menu__item">Another Action</li>
+            <li disabled class="mdl-menu__item">Disabled Action</li>
+            <li class="mdl-menu__item">Yet Another Action</li>
+          </ul>
+
+          <span>Menu top left</span>
+        </div>
+      </div>
+    </div>
+  </section>
+  -->
+
+  <!-- Menu button -->
+  <section style="padding-bottom:16px">
+    <h4>Menu button</h4>
+    <button class="mdl-button mdl-button--raised mdl-js-ripple-effect mdl-js-button mdlext-js-menu-button">
+      <i class="material-icons">gesture</i>
+      <span class="mdlext-menu-button__caption">Select</span>
+      <i class="material-icons mdlext-aria-expanded-more-less"></i>
+    </button>
+    <ul class="mdlext-menu mdlext-dark-color-theme" hidden >
+      <li class="mdlext-menu__item">
+        <i class="material-icons md-18">info</i>
+        <span class="mdlext-menu__item__caption">Menu item #1</span>
+      </li>
+      <li class="mdlext-menu__item">
+        <i class="material-icons md-18">help_outline</i>
+        <span class="mdlext-menu__item__caption">Menu item #2. A long text to check ellipsis overflow 0123456789</span>
+        <i class="material-icons md-18">radio</i>
+      </li>
+      <li class="mdlext-menu__item-separator"></li>
+      <li class="mdlext-menu__item" disabled>
+        <span class="mdlext-menu__item__caption">Menu item #3, disabled</span>
+        <i class="material-icons md-18">accessibility</i>
+      </li>
+      <li class="mdlext-menu__item-separator"></li>
+      <li class="mdlext-menu__item">
+        <span class="mdlext-menu__item__caption">Menu item #IV</span>
+        <i class="material-icons md-18">build</i>
+      </li>
+      <li class="mdlext-menu__item">
+        <span class="mdlext-menu__item__caption">Menu item #V</span>
+        <i class="material-icons md-18">build</i>
+      </li>
+      <li class="mdlext-menu__item-separator"></li>
+      <li class="mdlext-menu__item">
+        <span class="mdlext-menu__item__caption">Menu item #VI</span>
+        <i class="material-icons md-18">build</i>
+      </li>
+      <li class="mdlext-menu__item">
+        <span class="mdlext-menu__item__caption">Menu item #VII</span>
+        <i class="material-icons md-18">build</i>
+      </li>
+      <li class="mdlext-menu__item">
+        Menu item #n
+      </li>
+    </ul>
+  </section>
+
+
+</div>
+
+
+
+<h2>Default Color Theme</h2>
+
+<!-- Default theme -->
+<div class="demo-theme-container">
+
+  <section>
+    <table class="info">
+      <tr>
+        <th class="mdl-typography--caption-color-contrast">.mdl-typography--</th>
+        <td class="mdl-typography--title">Scale &amp; Basic Styles</td>
+      </tr>
+      <tr>
+        <th class="mdl-typography--caption-color-contrast">display-4</th>
+        <td class="mdl-typography--display-4">Light 112px</td>
+      </tr>
+      <tr>
+        <th class="mdl-typography--caption-color-contrast">display-3</th>
+        <td class="mdl-typography--display-3">Regular 56px</td>
+      </tr>
+      <tr>
+        <th class="mdl-typography--caption-color-contrast">display-2</th>
+        <td class="mdl-typography--display-2">Regular 45px</td>
+      </tr>
+      <tr>
+        <th class="mdl-typography--caption-color-contrast">display-1</th>
+        <td class="mdl-typography--display-1">Regular 34px</td>
+      </tr>
+      <tr>
+        <th class="mdl-typography--caption-color-contrast">headline</th>
+        <td class="mdl-typography--headline">Regular 24px</td>
+      </tr>
+      <tr>
+        <th class="mdl-typography--caption-color-contrast">title</th>
+        <td class="mdl-typography--title">Medium 20px</td>
+      </tr>
+      <tr>
+        <th class="mdl-typography--caption-color-contrast">subhead</th>
+        <td class="mdl-typography--subhead">Regular 16px (Device), Regular 15px (Desktop)</td>
+      </tr>
+      <tr>
+        <th class="mdl-typography--caption-color-contrast">body-2</th>
+        <td class="mdl-typography--body-2">Medium 14px (Device), Medium 13px (Desktop)</td>
+      </tr>
+      <tr>
+        <th class="mdl-typography--caption-color-contrast">body-1</th>
+        <td class="mdl-typography--body-1">Regular 14px (Device), Regular 13px (Desktop)</td>
+      </tr>
+      <tr>
+        <th class="mdl-typography--caption-color-contrast">body-2-force-preferred-font</th>
+        <td class="mdl-typography--body-2-force-preferred-font">Medium 14px (Device), Medium 13px (Desktop)</td>
+      </tr>
+      <tr>
+        <th class="mdl-typography--caption-color-contrast">body-1-force-preferred-font</th>
+        <td class="mdl-typography--body-1-force-preferred-font">Regular 14px (Device), Regular 13px (Desktop)</td>
+      </tr>
+      <tr>
+        <th class="mdl-typography--caption-color-contrast">caption</th>
+        <td class="mdl-typography--caption">Regular 12px</td>
+      </tr>
+      <tr>
+        <th class="mdl-typography--caption-color-contrast">menu</th>
+        <td class="mdl-typography--menu">Medium 14px (Device), Medium 13px (Desktop)</td>
+      </tr>
+      <tr>
+        <th class="mdl-typography--caption-color-contrast">button</th>
+        <td class="mdl-typography--button">Medium (All Caps) 14px</td>
+      </tr>
+
+      <tr>
+        <th class="mdl-typography--caption-color-contrast">primary-dark</th>
+        <td class="mdl-color--primary-dark mdl-color-text--primary-contrast">mdl-color--primary-dark mdl-color-text--primary-contrast</td>
+      </tr>
+      <tr>
+        <th class="mdl-typography--caption-color-contrast">primary</th>
+        <td class="mdl-color--primary mdl-color-text--primary-contrast">mdl-color--primary mdl-color-text--primary-contrast</td>
+      </tr>
+      <tr>
+        <th class="mdl-typography--caption-color-contrast">accent</th>
+        <td class="mdl-color--accent mdl-color-text--accent-contrast">mdl-color--accent mdl-color-text--accent-contrast</td>
+      </tr>
+      <tr>
+        <th class="mdl-typography--caption-color-contrast">primary-dark</th>
+        <td class="mdl-color--primary-contrast mdl-color-text--primary-dark">mdl-color--primary-contrast mdl-color-text--primary-dark</td>
+      </tr>
+      <tr>
+        <th class="mdl-typography--caption-color-contrast">primary</th>
+        <td class="mdl-color--primary-contrast mdl-color-text--primary">mdl-color-text--primary</td>
+      </tr>
+      <tr>
+        <th class="mdl-typography--caption-color-contrast">accent</th>
+        <td class="mdl-color--accent-contrast mdl-color-text--accent">mdl-color--accent-contrast mdl-color-text--accent</td>
+      </tr>
+    </table>
+  </section>
+
+  <section>
+    <h1>Base font</h1>
+
+    <p>Material Design Lite start’s with a base font of</p>
+    <ul>
+      <li>A size of 14px</li>
+      <li>A weight of 400</li>
+      <li>A line height of 20px</li>
+    </ul>
+
+    <p class="mdl-typography--body-1">Regular 14px (Device), Regular 13px (Desktop)</p>
+    <p class="mdl-typography--body-1-force-preferred-font">Regular 14px (Device), Regular 13px (Desktop)</p>
+    <p class="mdl-typography--body-2">Medium 14px (Device), Medium 13px (Desktop)</p>
+    <p class="mdl-typography--body-2-color-contrast">Body with color contrast</p>
+    <p class="mdl-typography--body-2-force-preferred-font">Medium 14px (Device), Medium 13px (Desktop)</p>
+    <p><a href="#" onclick="return false">An anchor</a></p>
+
+    <h1>Headings</h1>
+    <h1>h1 (56px) <small>Subtitle</small></h1>
+    <h2>h2 (45px) <small>Subtitle</small></h2>
+    <h3>h3 (34px) <small>Subtitle</small></h3>
+    <h4>h4 (24px) <small>Subtitle</small></h4>
+    <h5>h5 (20px) <small>Subtitle</small></h5>
+    <h6>h6 (16px) <small>Subtitle</small></h6>
+  </section>
+
+
+  <!-- textfields -->
+  <section class = "textfield-demo-container">
+
+    <div class="mdl-grid mdl-grid--no-spacing">
+
+      <div class="mdl-cell mdl-cell--4-col">
+        <div class="mdl-textfield mdl-js-textfield">
+          <input class="mdl-textfield__input" type="text">
+          <label class="mdl-textfield__label">Text...</label>
+        </div>
+      </div>
+
+      <div class="mdl-cell mdl-cell--4-col">
+        <div class="mdl-textfield mdl-js-textfield">
+          <input class="mdl-textfield__input" type="text" pattern="-?[0-9]*(\.[0-9]+)?">
+          <label class="mdl-textfield__label">Number...</label>
+          <span class="mdl-textfield__error">Input is not a number!</span>
+        </div>
+      </div>
+
+      <div class="mdl-cell mdl-cell--4-col">
+        <div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label">
+          <input class="mdl-textfield__input" type="text" list="languages" placeholder="Select a programming language" required>
+          <label class="mdl-textfield__label">Programming Language</label>
+        </div>
+      </div>
+
+      <div class="mdl-cell mdl-cell--4-col">
+        <div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label">
+          <input class="mdl-textfield__input" type="text" pattern="-?[0-9]*(\.[0-9]+)?">
+          <label class="mdl-textfield__label">Number...</label>
+          <span class="mdl-textfield__error">Input is not a number!</span>
+        </div>
+      </div>
+
+      <div class="mdl-cell mdl-cell--4-col">
+        <div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label">
+          <input class="mdl-textfield__input" type="text" pattern="-?[0-9]*(\.[0-9]+)?" disabled value="123">
+          <label class="mdl-textfield__label">Number...</label>
+          <span class="mdl-textfield__error">Input is not a number!</span>
+        </div>
+      </div>
+
+      <div class="mdl-cell mdl-cell--4-col">
+        <div class="mdl-textfield mdl-js-textfield mdl-textfield--expandable mdl-textfield--floating-label">
+          <label class="mdl-button mdl-js-button mdl-button--icon" for="mdl-expandable-demo1">
+            <i class="material-icons">search</i>
+          </label>
+          <div class="mdl-textfield__expandable-holder">
+            <input class="mdl-textfield__input" type="text" name="q" value="" id="mdl-expandable-demo1" pattern=".{3,}" />
+            <label class="mdl-textfield__label" for="mdl-expandable-demo1">Expandable Input</label>
+          </div>
+        </div>
+      </div>
+
+      <div class="mdl-cell mdl-cell--8-col">
+        <div class="mdl-textfield mdl-js-textfield mdl-textfield--full-width mdl-textfield--floating-label">
+          <textarea class="mdl-textfield__input" rows= "3"></textarea>
+          <label class="mdl-textfield__label">Text lines...</label>
+        </div>
+      </div>
+
+    </div>
+
+  </section>
+
+
+  <!-- Selectfield -->
+  <section style="margin-bottom: 16px;">
+    <div class="mdl-grid mdl-grid--no-spacing">
+
+      <div class="mdl-cell mdl-cell--4-col">
+        <div class="mdlext-selectfield mdlext-js-selectfield">
+          <select class="mdlext-selectfield__select">
+            <option value=""></option>
+            <option value="option1">option 1</option>
+            <option value="option2">option 2</option>
+            <option value="option3">option 3</option>
+            <option value="option4">option 4</option>
+            <option value="option5">option 5</option>
+          </select>
+          <label class="mdlext-selectfield__label">Profession</label>
+        </div>
+      </div>
+
+      <div class="mdl-cell mdl-cell--4-col">
+        <div class="mdlext-selectfield mdlext-js-selectfield mdlext-selectfield--floating-label">
+          <select class="mdlext-selectfield__select">
+            <option value=""></option>
+            <option value="option1">option 1</option>
+            <option value="option2">option 2</option>
+            <option value="option3">option 3</option>
+            <option value="option4">option 4</option>
+            <option value="option5">option 5</option>
+          </select>
+          <label class="mdlext-selectfield__label">Profession</label>
+        </div>
+      </div>
+
+      <div class="mdl-cell mdl-cell--4-col">
+        <div class="mdlext-selectfield mdlext-js-selectfield mdlext-selectfield--floating-label">
+          <select class="mdlext-selectfield__select" disabled>
+            <option value=""></option>
+            <option value="option1">option 1</option>
+            <option value="option2">option 2</option>
+            <option value="option3">option 3</option>
+            <option value="option4">option 4</option>
+            <option value="option5">option 5</option>
+          </select>
+          <label class="mdlext-selectfield__label">Profession</label>
+        </div>
+      </div>
+    </div>
+  </section>
+
+
+
+  <!-- bordered fields -->
+  <section class="mdlext-bordered-fields" style="margin-top:16px;">
+
+    <div class="mdl-grid mdl-grid--no-spacing">
+
+      <div class="mdl-cell mdl-cell--4-col">
+        <div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label">
+          <input class="mdl-textfield__input" type="text" list="languages" placeholder="Select a language" required>
+          <label class="mdl-textfield__label">Programming language</label>
+        </div>
+      </div>
+
+      <div class="mdl-cell mdl-cell--4-col">
+        <div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label">
+          <input class="mdl-textfield__input" type="text" pattern="-?[0-9]*(\.[0-9]+)?">
+          <label class="mdl-textfield__label">Numeric with floating label</label>
+          <span class="mdl-textfield__error">Input is not a number!</span>
+        </div>
+      </div>
+
+      <div class="mdl-cell mdl-cell--4-col">
+        <div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label">
+          <input class="mdl-textfield__input" type="text" pattern="-?[0-9]*(\.[0-9]+)?" disabled value="123">
+          <label class="mdl-textfield__label" >Disabled floating label</label>
+          <span class="mdl-textfield__error">Input is not a number!</span>
+        </div>
+      </div>
+
+      <div class="mdl-cell mdl-cell--4-col">
+        <div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label mdlext-bordered-fields__icon-right ">
+          <input class="mdl-textfield__input" type="text" id="uploadfile33" readonly>
+          <label class="mdl-textfield__label">File (work in progress)</label>
+
+          <label class="mdl-button mdl-js-button mdl-button--primary mdl-button--icon mdl-button--file" for="uploadfile33">
+            <i class="material-icons">attach_file</i>
+            <input type="file" id="uploadBtn33">
+          </label>
+        </div>
+        <!--
+          // Need a script to work properly - something like this
+        -->
+        <script>
+          (function() {
+            'use strict';
+            document.querySelector('#uploadBtn33').addEventListener('change', function() {
+              var n = document.querySelector("#uploadfile33");
+              n.value = this.files[0].name;
+              n.parentNode.classList.add('is-dirty');
+            });
+          }());
+        </script>
+      </div>
+
+      <div class="mdl-cell mdl-cell--4-col">
+        <div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label mdlext-bordered-fields__icon-left mdlext-bordered-fields__icon-right">
+          <i class="material-icons">radio</i>
+          <input class="mdl-textfield__input" type="text" disabled>
+          <label class="mdl-textfield__label">Text, disabled</label>
+          <i class="material-icons">fingerprint</i>
+        </div>
+      </div>
+
+
+      <div class="mdl-cell mdl-cell--4-col">
+        <div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label mdlext-bordered-fields__icon-left">
+          <label class="mdl-button mdl-js-button mdl-button--icon">
+            <i class="material-icons">phone</i>
+          </label>
+
+          <input class="mdl-textfield__input" type="text">
+          <label class="mdl-textfield__label">Text...</label>
+        </div>
+      </div>
+
+      <div class="mdl-cell mdl-cell--4-col">
+        <div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label mdlext-bordered-fields__icon-right">
+          <input class="mdl-textfield__input" type="text">
+          <label class="mdl-textfield__label">Text...</label>
+
+          <label class="mdl-button mdl-js-button mdl-button--icon">
+            <i class="material-icons">settings_voice</i>
+          </label>
+        </div>
+      </div>
+
+
+      <div class="mdl-cell mdl-cell--4-col">
+        <div class="mdlext-selectfield mdlext-js-selectfield mdlext-selectfield--floating-label">
+          <select class="mdlext-selectfield__select">
+            <option value=""></option>
+            <option value="option1">option 1</option>
+            <option value="option2">option 2</option>
+            <option value="option3">option 3</option>
+            <option value="option4">option 4</option>
+            <option value="option5">option 5</option>
+          </select>
+          <label class="mdlext-selectfield__label">Profession</label>
+        </div>
+      </div>
+
+      <div class="mdl-cell mdl-cell--4-col">
+        <div class="mdlext-selectfield mdlext-js-selectfield mdlext-selectfield--floating-label">
+          <select class="mdlext-selectfield__select" disabled>
+            <option value=""></option>
+            <option value="option1">option 1</option>
+            <option value="option2">option 2</option>
+            <option value="option3">option 3</option>
+            <option value="option4">option 4</option>
+            <option value="option5">option 5</option>
+          </select>
+          <label class="mdlext-selectfield__label">Profession</label>
+        </div>
+      </div>
+
+      <div class="mdl-cell mdl-cell--4-col">
+        <div class="mdlext-selectfield mdlext-js-selectfield mdlext-selectfield--floating-label mdlext-bordered-fields__icon-left">
+          <label class="mdl-button mdl-js-button mdl-button--icon">
+            <i class="material-icons">phone</i>
+          </label>
+          <select class="mdlext-selectfield__select">
+            <option value=""></option>
+            <option value="option1">option 1</option>
+            <option value="option2">option 2</option>
+            <option value="option3">option 3</option>
+            <option value="option4">option 4</option>
+            <option value="option5">option 5</option>
+          </select>
+          <label class="mdlext-selectfield__label">Profession</label>
+        </div>
+      </div>
+
+      <div class="mdl-cell mdl-cell--4-col">
+        <div class="mdlext-selectfield mdlext-js-selectfield mdlext-selectfield--floating-label mdlext-bordered-fields__icon-left">
+          <label class="mdl-button mdl-js-button mdl-button--icon">
+            <i class="material-icons">phone</i>
+          </label>
+          <select class="mdlext-selectfield__select" disabled>
+            <option value=""></option>
+            <option value="option1">option 1</option>
+            <option value="option2">option 2</option>
+            <option value="option3">option 3</option>
+            <option value="option4">option 4</option>
+            <option value="option5">option 5</option>
+          </select>
+          <label class="mdlext-selectfield__label">Profession</label>
+        </div>
+      </div>
+
+
+
+      <div class="mdl-cell mdl-cell--4-col">
+        <div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label mdlext-bordered-fields__icon-left">
+          <i class="material-icons">radio</i>
+          <input class="mdl-textfield__input" type="text">
+          <label class="mdl-textfield__label">Text...</label>
+        </div>
+      </div>
+
+      <div class="mdl-cell mdl-cell--4-col">
+        <div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label mdlext-bordered-fields__icon-right">
+          <input class="mdl-textfield__input" type="text">
+          <label class="mdl-textfield__label">Text...</label>
+          <i class="material-icons">fingerprint</i>
+        </div>
+      </div>
+
+      <div class="mdl-cell mdl-cell--4-col">
+        <div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label mdlext-bordered-fields__icon-left mdlext-bordered-fields__icon-right">
+          <i class="material-icons">radio</i>
+          <input class="mdl-textfield__input" type="text">
+          <label class="mdl-textfield__label">Text...</label>
+          <i class="material-icons">fingerprint</i>
+        </div>
+      </div>
+
+      <div class="mdl-cell mdl-cell--4-col">
+        <div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label mdlext-bordered-fields__icon-left mdlext-bordered-fields__icon-right">
+          <label class="mdl-button mdl-js-button mdl-button--icon">
+            <i class="material-icons">phone</i>
+          </label>
+
+          <input class="mdl-textfield__input" type="text">
+          <label class="mdl-textfield__label">Text...</label>
+
+          <label class="mdl-button mdl-js-button mdl-button--icon">
+            <i class="material-icons">settings_voice</i>
+          </label>
+        </div>
+      </div>
+
+      <div class="mdl-cell mdl-cell--4-col">
+        <div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label mdlext-bordered-fields__icon-left mdlext-bordered-fields__icon-right">
+          <label class="mdl-button mdl-js-button mdl-button--icon">
+            <i class="material-icons">phone</i>
+          </label>
+
+          <input class="mdl-textfield__input" type="text" disabled>
+          <label class="mdl-textfield__label">Text...</label>
+
+          <label class="mdl-button mdl-js-button mdl-button--icon">
+            <i class="material-icons">settings_voice</i>
+          </label>
+        </div>
+      </div>
+
+      <div class="mdl-cell mdl-cell--4-col">
+        <div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label mdlext-bordered-fields__icon-left mdlext-bordered-fields__icon-right">
+          <i class="material-icons">radio</i>
+          <input class="mdl-textfield__input" type="text">
+          <label class="mdl-textfield__label">Text...</label>
+          <label class="mdl-button mdl-js-button mdl-button--icon">
+            <i class="material-icons">settings_voice</i>
+          </label>
+        </div>
+      </div>
+
+    </div>
+
+  </section>
+
+
+  <!-- Badges -->
+  <section style="margin-top:16px">
+    <div class="mdl-grid demo-badge-grid">
+      <div class="mdl-cell mdl-cell--2-col">
+        <span class="mdl-badge" data-badge="4">Inbox</span>
+      </div>
+      <div class="mdl-cell mdl-cell--2-col">
+        <span class="material-icons mdl-badge" data-badge="1">account_box</span>
+      </div>
+      <div class="mdl-cell mdl-cell--2-col">
+        <span class="mdl-badge" data-badge="♥">Mood</span>
+      </div>
+      <div class="mdl-cell mdl-cell--2-col">
+        <span class="material-icons mdl-badge" data-badge="♥">account_box</span>
+      </div>
+      <div class="mdl-cell mdl-cell--2-col">
+        <a href="#" onclick="return false" class="mdl-badge" data-badge="5">Inbox</a>
+      </div>
+    </div>
+  </section>
+
+  <!-- Buttons -->
+  <section>
+    <div class="mdl-grid demo-button-grid">
+      <div class="mdl-cell mdl-cell--2-col mdl-cell--middle">
+        <button class="mdl-button mdl-js-button mdl-button--fab mdl-button--colored">
+          <i class="material-icons">add</i>
+        </button>
+      </div>
+      <div class="mdl-cell mdl-cell--2-col mdl-cell--middle">
+        <button class="mdl-button mdl-js-button mdl-button--fab">
+          <i class="material-icons">add</i>
+        </button>
+      </div>
+      <div class="mdl-cell mdl-cell--2-col mdl-cell--middle">
+        <button class="mdl-button mdl-js-button mdl-button--fab" disabled>
+          <i class="material-icons">add</i>
+        </button>
+      </div>
+
+      <div class="mdl-cell mdl-cell--2-col mdl-cell--middle">
+        <button class="mdl-button mdl-js-button mdl-button--fab mdl-button--mini-fab mdl-button--colored">
+          <i class="material-icons">add</i>
+        </button>
+      </div>
+      <div class="mdl-cell mdl-cell--2-col mdl-cell--middle">
+        <button class="mdl-button mdl-js-button mdl-button--fab mdl-button--mini-fab">
+          <i class="material-icons">add</i>
+        </button>
+      </div>
+      <div class="mdl-cell mdl-cell--2-col mdl-cell--middle">
+        <button class="mdl-button mdl-js-button mdl-button--fab mdl-button--mini-fab" disabled>
+          <i class="material-icons">add</i>
+        </button>
+      </div>
+
+      <div class="mdl-cell mdl-cell--2-col mdl-cell--middle">
+        <button class="mdl-button mdl-js-button mdl-button--raised">
+          Raised
+        </button>
+      </div>
+      <div class="mdl-cell mdl-cell--2-col mdl-cell--middle">
+        <button class="mdl-button mdl-js-button mdl-button--raised" disabled>
+          Disabled
+        </button>
+      </div>
+
+      <div class="mdl-cell mdl-cell--2-col mdl-cell--middle">
+        <button class="mdl-button mdl-js-button mdl-button--raised mdl-button--colored">
+          Colored
+        </button>
+      </div>
+      <div class="mdl-cell mdl-cell--2-col mdl-cell--middle">
+        <button class="mdl-button mdl-js-button mdl-button--raised mdl-button--accent">
+          Accent
+        </button>
+      </div>
+
+      <div class="mdl-cell mdl-cell--2-col mdl-cell--middle">
+        <button class="mdl-button mdl-js-button mdl-button--raised mdl-button--colored mdl-js-ripple-effect">
+          <i class="material-icons">settings</i>&nbsp;Settings
+        </button>
+      </div>
+
+      <div class="mdl-cell mdl-cell--2-col mdl-cell--middle">
+        <button class="mdl-button mdl-js-button mdl-button--raised mdl-button--accent mdl-js-ripple-effect animated bounce">
+          <i class="material-icons">favorite</i>&nbsp;Fav
+        </button>
+      </div>
+
+      <div class="mdl-cell mdl-cell--2-col mdl-cell--middle">
+        <button class="mdl-button mdl-js-button">
+          Flat
+        </button>
+      </div>
+      <div class="mdl-cell mdl-cell--2-col mdl-cell--middle">
+        <button class="mdl-button mdl-js-button" disabled>
+          Disabled
+        </button>
+      </div>
+
+      <div class="mdl-cell mdl-cell--2-col mdl-cell--middle">
+        <button class="mdl-button mdl-js-button mdl-button--primary">
+          Colored
+        </button>
+      </div>
+      <div class="mdl-cell mdl-cell--2-col mdl-cell--middle">
+        <button class="mdl-button mdl-js-button mdl-button--accent">
+          Accent
+        </button>
+      </div>
+
+      <div class="mdl-cell mdl-cell--2-col mdl-cell--middle">
+        <button class="mdl-button mdl-js-button">
+          <i class="material-icons">snooze</i>&nbsp;Ring, ring...
+        </button>
+      </div>
+
+      <div class="mdl-cell mdl-cell--2-col mdl-cell--middle">
+        <button class="mdl-button mdl-js-button mdl-button--icon">
+          <i class="material-icons">mood</i>
+        </button>
+      </div>
+      <div class="mdl-cell mdl-cell--2-col mdl-cell--middle">
+        <button class="mdl-button mdl-js-button mdl-button--icon mdl-button--colored">
+          <i class="material-icons">mood</i>
+        </button>
+      </div>
+      <div class="mdl-cell mdl-cell--2-col mdl-cell--middle">
+        <button class="mdl-button mdl-js-button mdl-button--fab mdl-color--lime mdl-button--accent">
+          <i class="material-icons">cloud</i>
+        </button>
+      </div>
+
+      <div class="mdl-cell mdl-cell--2-col mdl-cell--middle">
+        <button class="mdl-button mdl-js-button mdl-button--raised mdl-color--deep-orange-100 mdl-js-ripple-effect">
+          <i class="material-icons">settings</i>&nbsp;Settings
+        </button>
+      </div>
+    </div>
+  </section>
+
+
+  <!-- Toggles -->
+  <section>
+    <div class="mdl-grid demo-toggle-grid">
+      <div class="mdl-cell mdl-cell--2-col">
+        <label class="mdl-checkbox mdl-js-checkbox mdl-js-ripple-effect">
+          <input type="checkbox" class="mdl-checkbox__input" checked>
+          <span class="mdl-checkbox__label">Checkbox</span>
+        </label>
+      </div>
+      <div class="mdl-cell mdl-cell--2-col">
+        <label class="mdl-checkbox mdl-js-checkbox mdl-js-ripple-effect">
+          <input type="checkbox" class="mdl-checkbox__input">
+          <span class="mdl-checkbox__label">Checkbox</span>
+        </label>
+      </div>
+      <div class="mdl-cell mdl-cell--2-col">
+        <label class="mdl-checkbox mdl-js-checkbox mdl-js-ripple-effect">
+          <input type="checkbox" class="mdl-checkbox__input" checked disabled>
+          <span class="mdl-checkbox__label">Checkbox</span>
+        </label>
+      </div>
+
+      <div class="mdl-cell mdl-cell--2-col">
+        <label class="mdl-radio mdl-js-radio mdl-js-ripple-effect">
+          <input type="radio" class="mdl-radio__button" name="options" value="1" checked>
+          <span class="mdl-radio__label">First</span>
+        </label>
+      </div>
+      <div class="mdl-cell mdl-cell--2-col">
+        <label class="mdl-radio mdl-js-radio mdl-js-ripple-effect">
+          <input type="radio" class="mdl-radio__button" name="options" value="2">
+          <span class="mdl-radio__label">Second</span>
+        </label>
+      </div>
+      <div class="mdl-cell mdl-cell--2-col">
+        <label class="mdl-radio mdl-js-radio mdl-js-ripple-effect">
+          <input type="radio" class="mdl-radio__button" name="options" value="3" disabled>
+          <span class="mdl-radio__label">Third</span>
+        </label>
+      </div>
+
+      <div class="mdl-cell mdl-cell--2-col">
+        <label class="mdl-icon-toggle mdl-js-icon-toggle mdl-js-ripple-effect">
+          <input type="checkbox" class="mdl-icon-toggle__input" checked>
+          <i class="mdl-icon-toggle__label material-icons">format_bold</i>
+        </label>
+      </div>
+      <div class="mdl-cell mdl-cell--2-col">
+        <label class="mdl-icon-toggle mdl-js-icon-toggle mdl-js-ripple-effect">
+          <input type="checkbox" class="mdl-icon-toggle__input">
+          <i class="mdl-icon-toggle__label material-icons">format_italic</i>
+        </label>
+      </div>
+      <div class="mdl-cell mdl-cell--2-col">
+        <label class="mdl-icon-toggle mdl-js-icon-toggle mdl-js-ripple-effect">
+          <input type="checkbox" class="mdl-icon-toggle__input" disabled>
+          <i class="mdl-icon-toggle__label material-icons">format_italic</i>
+        </label>
+      </div>
+
+      <div class="mdl-cell mdl-cell--2-col">
+        <label class="mdl-switch mdl-js-switch mdl-js-ripple-effect">
+          <input type="checkbox" class="mdl-switch__input" checked>
+          <span class="mdl-switch__label"></span>
+        </label>
+      </div>
+      <div class="mdl-cell mdl-cell--2-col">
+        <label class="mdl-switch mdl-js-switch mdl-js-ripple-effect">
+          <input type="checkbox" class="mdl-switch__input">
+          <span class="mdl-switch__label"></span>
+        </label>
+      </div>
+      <div class="mdl-cell mdl-cell--2-col">
+        <label class="mdl-switch mdl-js-switch mdl-js-ripple-effect">
+          <input type="checkbox" class="mdl-switch__input" disabled>
+          <span class="mdl-switch__label"></span>
+        </label>
+      </div>
+    </div>
+  </section>
+
+
+  <!-- Sliders -->
+  <section>
+    <div class="mdl-grid demo-slider-grid">
+      <div class="mdl-cell mdl-cell--4-col mdl-cell--2-col-phone">
+        <!-- Default Slider -->
+        <input class="mdl-slider mdl-js-slider" type="range" min="0" max="100" value="0">
+      </div>
+
+      <div class="mdl-cell mdl-cell--4-col mdl-cell--2-col-phone">
+        <!-- Slider with Starting Value -->
+        <input class="mdl-slider mdl-js-slider" type="range" min="0" max="100" value="25">
+      </div>
+    </div>
+  </section>
+
+
+  <!-- Data table -->
+  <section>
+    <table class="mdl-data-table mdl-js-data-table mdl-data-table--selectable mdl-shadow--2dp">
+      <thead>
+      <tr>
+        <th class="mdl-data-table__cell--non-numeric">Materials</th>
+        <th>Quantity</th>
+        <th>Unit price</th>
+      </tr>
+      </thead>
+      <tbody>
+      <tr>
+        <td class="mdl-data-table__cell--non-numeric">Acrylic (Transparent)</td>
+        <td>25</td>
+        <td>$2.90</td>
+      </tr>
+      <tr>
+        <td class="mdl-data-table__cell--non-numeric">Plywood (Birch)</td>
+        <td>50</td>
+        <td>$1.25</td>
+      </tr>
+      <tr>
+        <td class="mdl-data-table__cell--non-numeric">Laminate (Gold on Blue)</td>
+        <td>10</td>
+        <td>$2.35</td>
+      </tr>
+      </tbody>
+    </table>
+  </section>
+
+
+  <!-- Menu -->
+  <!--
+  <section>
+    <div class="demo-menu demo-menu__lower-left">
+      <div class="demo-menu-container mdl-shadow--2dp mdl-color--primary-dark mdl-color-text--primary-contrast">
+        <div class="demo-menu-bar">
+          <button id="demo-menu-lower-left" class="mdl-button mdl-js-button mdl-button--icon">
+            <i class="material-icons">more_vert</i>
+          </button>
+          <ul class="mdl-menu mdl-menu--bottom-left mdl-js-menu mdl-js-ripple-effect" for="demo-menu-lower-left">
+            <li class="mdl-menu__item">Some Action</li>
+            <li class="mdl-menu__item">Another Action</li>
+            <li disabled class="mdl-menu__item">Disabled Action</li>
+            <li class="mdl-menu__item">Yet Another Action</li>
+          </ul>
+
+          <span>Menu lower left</span>
+
+        </div>
+        <div class="demo-menu-background-light"></div>
+      </div>
+    </div>
+  </section>
+  -->
+
+  <!-- Menu button -->
+  <section style="padding-bottom:16px">
+    <h4>Menu button</h4>
+    <button class="mdl-button mdl-button--raised mdl-js-ripple-effect mdl-js-button mdlext-js-menu-button">
+      <i class="material-icons">gesture</i>
+      <span class="mdlext-menu-button__caption">Select</span>
+      <i class="material-icons mdlext-aria-expanded-more-less"></i>
+    </button>
+    <ul class="mdlext-menu" hidden >
+      <li class="mdlext-menu__item">
+        <i class="material-icons md-18">info</i>
+        <span class="mdlext-menu__item__caption">Menu item #1</span>
+      </li>
+      <li class="mdlext-menu__item">
+        <i class="material-icons md-18">help_outline</i>
+        <span class="mdlext-menu__item__caption">Menu item #2. A long text to check ellipsis overflow 0123456789</span>
+        <i class="material-icons md-18">radio</i>
+      </li>
+      <li class="mdlext-menu__item-separator"></li>
+      <li class="mdlext-menu__item" disabled>
+        <span class="mdlext-menu__item__caption">Menu item #3, disabled</span>
+        <i class="material-icons md-18">accessibility</i>
+      </li>
+      <li class="mdlext-menu__item-separator"></li>
+      <li class="mdlext-menu__item">
+        <span class="mdlext-menu__item__caption">Menu item #IV</span>
+        <i class="material-icons md-18">build</i>
+      </li>
+      <li class="mdlext-menu__item">
+        <span class="mdlext-menu__item__caption">Menu item #V</span>
+        <i class="material-icons md-18">build</i>
+      </li>
+      <li class="mdlext-menu__item-separator"></li>
+      <li class="mdlext-menu__item">
+        <span class="mdlext-menu__item__caption">Menu item #VI</span>
+        <i class="material-icons md-18">build</i>
+      </li>
+      <li class="mdlext-menu__item">
+        <span class="mdlext-menu__item__caption">Menu item #VII</span>
+        <i class="material-icons md-18">build</i>
+      </li>
+      <li class="mdlext-menu__item">
+        Menu item #n
+      </li>
+    </ul>
+  </section>
+
+</div>
+
+
diff --git a/node_modules/mdl-ext/src/demo/accordion.html b/node_modules/mdl-ext/src/demo/accordion.html
new file mode 100644
index 0000000..6a65bda
--- /dev/null
+++ b/node_modules/mdl-ext/src/demo/accordion.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <include src="include/_head.html"></include>
+  <title>Material Design Lite Extensions - Accordion</title>
+</head>
+<body>
+<div class="mdl-layout mdl-js-layout mdl-layout--fixed-drawer mdl-layout--fixed-header">
+  <include src="include/_header.html"></include>
+  <include src="include/_drawer.html"></include>
+  <main id="mount" class="mdl-layout__content">
+    <include src="../../src/accordion/snippets/accordion.html"></include>
+  </main>
+</div>
+<include src="include/_scripts.html"></include>
+
+<script>
+  (function() {
+    'use strict';
+    document.addEventListener('DOMContentLoaded', function() {
+      var title = document.querySelector('#header-title');
+      if(title) {
+        title.innerHTML = 'Accordion';
+      }
+    });
+  }());
+</script>
+
+</body>
+</html>
diff --git a/node_modules/mdl-ext/src/demo/assets/android-desktop.png b/node_modules/mdl-ext/src/demo/assets/android-desktop.png
new file mode 100644
index 0000000..f4408f5
--- /dev/null
+++ b/node_modules/mdl-ext/src/demo/assets/android-desktop.png
Binary files differ
diff --git a/node_modules/mdl-ext/src/demo/assets/favicon.png b/node_modules/mdl-ext/src/demo/assets/favicon.png
new file mode 100644
index 0000000..11ec0b5
--- /dev/null
+++ b/node_modules/mdl-ext/src/demo/assets/favicon.png
Binary files differ
diff --git a/node_modules/mdl-ext/src/demo/assets/ios-desktop.png b/node_modules/mdl-ext/src/demo/assets/ios-desktop.png
new file mode 100644
index 0000000..ac65454
--- /dev/null
+++ b/node_modules/mdl-ext/src/demo/assets/ios-desktop.png
Binary files differ
diff --git a/node_modules/mdl-ext/src/demo/assets/welcome_card.jpg b/node_modules/mdl-ext/src/demo/assets/welcome_card.jpg
new file mode 100644
index 0000000..8003e3a
--- /dev/null
+++ b/node_modules/mdl-ext/src/demo/assets/welcome_card.jpg
Binary files differ
diff --git a/node_modules/mdl-ext/src/demo/bordered-fields.html b/node_modules/mdl-ext/src/demo/bordered-fields.html
new file mode 100644
index 0000000..f1b2dae
--- /dev/null
+++ b/node_modules/mdl-ext/src/demo/bordered-fields.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <include src="include/_head.html"></include>
+  <title>Material Design Lite Extensions - Bordered Fields</title>
+</head>
+<body>
+<div class="mdl-layout mdl-js-layout mdl-layout--fixed-drawer mdl-layout--fixed-header">
+  <include src="include/_header.html"></include>
+  <include src="include/_drawer.html"></include>
+  <main id="mount" class="mdl-layout__content">
+    <include src="../../src/bordered-fields/snippets/bordered-fields.html"></include>
+  </main>
+</div>
+<include src="include/_scripts.html"></include>
+<script>
+  (function() {
+    'use strict';
+    document.addEventListener('DOMContentLoaded', function() {
+      var title = document.querySelector('#header-title');
+      if(title) {
+        title.innerHTML = 'Bordered Fields';
+      }
+    });
+  }());
+</script>
+
+</body>
+</html>
diff --git a/node_modules/mdl-ext/src/demo/carousel.html b/node_modules/mdl-ext/src/demo/carousel.html
new file mode 100644
index 0000000..ddd66e0
--- /dev/null
+++ b/node_modules/mdl-ext/src/demo/carousel.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <include src="include/_head.html"></include>
+  <title>Material Design Lite Extensions - Carousel</title>
+</head>
+<body>
+<div class="mdl-layout mdl-js-layout mdl-layout--fixed-drawer mdl-layout--fixed-header">
+  <include src="include/_header.html"></include>
+  <include src="include/_drawer.html"></include>
+  <main id="mount" class="mdl-layout__content">
+    <include src="../../src/carousel/snippets/carousel.html"></include>
+  </main>
+</div>
+<include src="include/_scripts.html"></include>
+<script>
+  (function() {
+    'use strict';
+    document.addEventListener('DOMContentLoaded', function() {
+      var title = document.querySelector('#header-title');
+      if(title) {
+        title.innerHTML = 'Carousel';
+      }
+    });
+  }());
+</script>
+</body>
+</html>
diff --git a/node_modules/mdl-ext/src/demo/chrome-ripple-issue.html b/node_modules/mdl-ext/src/demo/chrome-ripple-issue.html
new file mode 100644
index 0000000..363a295
--- /dev/null
+++ b/node_modules/mdl-ext/src/demo/chrome-ripple-issue.html
@@ -0,0 +1,84 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+  <meta charset="UTF-8">
+  <title>Chrome Ripple Issue</title>
+  <!-- styles -->
+  <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:regular,bold,italic,thin,light,bolditalic,black,medium&amp;lang=en">
+  <link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
+  <link rel="stylesheet" href="https://code.getmdl.io/1.2.1/material.indigo-pink.min.css">
+</head>
+<body>
+<!-- Always shows a header, even in smaller screens. -->
+<div class="mdl-layout mdl-js-layout mdl-layout--fixed-header">
+  <header class="mdl-layout__header">
+    <div class="mdl-layout__header-row">
+      <!-- Title -->
+      <span class="mdl-layout-title">Title</span>
+      <!-- Add spacer, to align navigation to the right -->
+      <div class="mdl-layout-spacer"></div>
+      <!-- Navigation. We hide it in small screens. -->
+      <nav class="mdl-navigation mdl-layout--large-screen-only">
+        <a class="mdl-navigation__link" href="">Link</a>
+        <a class="mdl-navigation__link" href="">Link</a>
+        <a class="mdl-navigation__link" href="">Link</a>
+        <a class="mdl-navigation__link" href="">Link</a>
+      </nav>
+    </div>
+  </header>
+  <div class="mdl-layout__drawer">
+    <span class="mdl-layout-title">Title</span>
+    <nav class="mdl-navigation">
+      <a class="mdl-navigation__link" href="">Link</a>
+      <a class="mdl-navigation__link" href="">Link</a>
+      <a class="mdl-navigation__link" href="">Link</a>
+      <a class="mdl-navigation__link" href="">Link</a>
+    </nav>
+  </div>
+  <main class="mdl-layout__content">
+    <div class="page-content" style="padding: 128px 0 0 32px"><!-- Your content goes here -->
+
+      <h2>Ripple Issue</h2>
+      <ul>
+        <li>What MDL Version: material-design-lite-1.2.1</li>
+        <li>What browser(s) is this bug affecting (including version)? Chrome Version 53.0.2785.116 (64-bit)</li>
+        <li>What OS (and version) are you using? OSX, 10.11.6</li>
+        <li>What are the steps to reproduce the bug?
+          <ol>
+            <li>Resize browser until a scrollbar appears</li>
+            <li>Scroll the menu button into view</li>
+            <li>It's important to scroll, at least some pixels, to see the effect of this issue</li>
+            <li>Click the button to open the menu</li>
+            <li>The position of the content changes position while button ripple is animatings</li>
+            <li>Click on a menu item to close the menu</li>
+            <li>The position of the content changes while menu ripple is animating</li>
+          </ol>
+        </li>
+        <li>What is the expected behavior? The position of the should stay fixed</li>
+        <li>What is the actual behavior? The position of the page content changes</li>
+      </ul>
+
+      <div style="margin: 32px 0 640px 32px;">
+        <p><strong>Click the button</strong></p>
+        <button id="demo-menu-lower-left" style="height:46px; width:46px;"
+                class="mdl-button mdl-js-button mdl-button--icon mdl-js-ripple-effect">
+          <i class="material-icons">more_vert</i>
+        </button>
+
+        <ul class="mdl-menu mdl-menu--bottom-left mdl-js-menu mdl-js-ripple-effect"
+            for="demo-menu-lower-left">
+          <li class="mdl-menu__item">Some Action</li>
+          <li class="mdl-menu__item mdl-menu__item--full-bleed-divider">Another Action</li>
+          <li disabled class="mdl-menu__item">Disabled Action</li>
+          <li class="mdl-menu__item">Yet Another Action</li>
+        </ul>
+      </div>
+
+      <p>Some text</p>
+
+    </div>
+  </main>
+</div>
+<script src="https://code.getmdl.io/1.2.1/material.min.js" type="text/javascript" charset="utf-8"></script>
+</body>
+</html>
diff --git a/node_modules/mdl-ext/src/demo/collapsible.html b/node_modules/mdl-ext/src/demo/collapsible.html
new file mode 100644
index 0000000..c685333
--- /dev/null
+++ b/node_modules/mdl-ext/src/demo/collapsible.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <include src="include/_head.html"></include>
+  <title>Material Design Lite Extensions - Menu Button</title>
+</head>
+<body>
+<div class="mdl-layout mdl-js-layout mdl-layout--fixed-drawer mdl-layout--fixed-header">
+  <include src="include/_header.html"></include>
+  <include src="include/_drawer.html"></include>
+  <main id="mount" class="mdl-layout__content">
+    <include src="../../src/collapsible/snippets/collapsible.html"></include>
+  </main>
+</div>
+<include src="include/_scripts.html"></include>
+<script>
+  (function() {
+    'use strict';
+    document.addEventListener('DOMContentLoaded', function() {
+      var title = document.querySelector('#header-title');
+      if(title) {
+        title.innerHTML = 'Collapsible';
+      }
+    });
+  }());
+</script>
+</body>
+</html>
diff --git a/node_modules/mdl-ext/src/demo/color-themes.html b/node_modules/mdl-ext/src/demo/color-themes.html
new file mode 100644
index 0000000..390e0b3
--- /dev/null
+++ b/node_modules/mdl-ext/src/demo/color-themes.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <include src="include/_head.html"></include>
+  <title>Material Design Lite Extensions - Color Themes</title>
+</head>
+<body>
+<div class="mdl-layout mdl-js-layout mdl-layout--fixed-drawer mdl-layout--fixed-header">
+  <include src="include/_header.html"></include>
+  <include src="include/_drawer.html"></include>
+  <main id="mount" class="mdl-layout__content">
+    <include src="../../src/color-themes/snippets/color-themes.html"></include>
+  </main>
+</div>
+<include src="include/_scripts.html"></include>
+<script>
+  (function() {
+    'use strict';
+    document.addEventListener('DOMContentLoaded', function() {
+      var title = document.querySelector('#header-title');
+      if(title) {
+        title.innerHTML = 'Color Themes';
+      }
+    });
+  }());
+</script>
+</body>
+</html>
diff --git a/node_modules/mdl-ext/src/demo/etc/buildpages.js b/node_modules/mdl-ext/src/demo/etc/buildpages.js
new file mode 100644
index 0000000..4671609
--- /dev/null
+++ b/node_modules/mdl-ext/src/demo/etc/buildpages.js
@@ -0,0 +1,15 @@
+'use strict';
+
+// TODO: Automate this. Use Gulp
+const posthtml = require('posthtml');
+const html = require('fs').readFileSync('partials/lightbox.html').toString();
+
+posthtml()
+  .use(require('posthtml-include')({ encoding: 'utf-8', root: 'partials/' }))
+  .process(html /*, options */)
+  .then(function(result) {
+    console.log(result.html);
+  })
+  .catch(function(error) {
+    console.error(error);
+  });
diff --git a/node_modules/mdl-ext/src/demo/etc/mdl-basic-component.html b/node_modules/mdl-ext/src/demo/etc/mdl-basic-component.html
new file mode 100644
index 0000000..cd4d22f
--- /dev/null
+++ b/node_modules/mdl-ext/src/demo/etc/mdl-basic-component.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+  <meta charset="UTF-8">
+  <title>A basic MDL component</title>
+  <link rel="stylesheet" href="../node_modules/material-design-lite/material.css" />
+</head>
+<body>
+  <div id="mount">
+    <div class="mdl-basic mdl-js-basic mdl-js-ripple-effect">
+      <p>My basic MDL component</p>
+    </div>
+  </div>
+  <script type="text/javascript" src="../node_modules/material-design-lite/material.js" charset="utf-8"></script>
+  <script type="text/javascript" src="./mdl-basic-component.js" charset="utf-8"></script>
+</body>
+</html>
diff --git a/node_modules/mdl-ext/src/demo/etc/mdl-basic-component.js b/node_modules/mdl-ext/src/demo/etc/mdl-basic-component.js
new file mode 100644
index 0000000..05db9c1
--- /dev/null
+++ b/node_modules/mdl-ext/src/demo/etc/mdl-basic-component.js
@@ -0,0 +1,79 @@
+(function() {
+  'use strict';
+
+  /**
+   * https://github.com/google/material-design-lite/issues/4205
+   * @constructor
+   * @param {Element} element The element that will be upgraded.
+   */
+  const MaterialBasic = function MaterialBasic(element) {
+    // Stores the element.
+    this.element_ = element;
+
+    console.log('***** ctor', this.element_.classList, 'data-upgraded', this.element_.getAttribute('data-upgraded'));
+
+    // Initialize instance.
+    this.init();
+  };
+  window['MaterialBasic'] = MaterialBasic;
+
+  /**
+   * Store constants in one place so they can be updated easily.
+   *
+   * @enum {string}
+   * @private
+   */
+  MaterialBasic.prototype.Constant_ = {
+    RIPPLE_COMPONENT: 'MaterialRipple'
+  };
+
+  /**
+   * Store strings for class names defined by this component that are used in
+   * JavaScript. This allows us to simply change it in one place should we
+   * decide to modify at a later date.
+   *
+   * @enum {string}
+   * @private
+   */
+  MaterialBasic.prototype.CssClasses_ = {
+    IS_UPGRADED: 'is-upgraded',
+    JS_RIPPLE_EFFECT: 'mdl-js-ripple-effect',
+    JS_RIPPLE_EFFECT_IGNORE_EVENTS: 'mdl-js-ripple-effect--ignore-events'
+  };
+
+  /**
+   * Initialize component
+   */
+  MaterialBasic.prototype.init = function() {
+    console.log('***** init', this.element_.classList, 'data-upgraded', this.element_.getAttribute('data-upgraded'));
+
+    if (this.element_) {
+      if (this.element_.classList.contains(this.CssClasses_.JS_RIPPLE_EFFECT)) {
+        this.element_.classList.add(this.CssClasses_.JS_RIPPLE_EFFECT_IGNORE_EVENTS);
+      }
+
+      // Do the init required for this component to work
+
+      // Set upgraded flag
+      this.element_.classList.add(this.CssClasses_.IS_UPGRADED);
+    }
+  };
+
+  /**
+   * Downgrade component
+   * E.g remove listeners and clean up resources
+   */
+  MaterialBasic.prototype.mdlDowngrade_ = function() {
+    'use strict';
+  };
+
+  // The component registers itself. It can assume componentHandler is available
+  // in the global scope.
+  /* eslint no-undef: 0 */
+  /* jshint undef:false */
+  componentHandler.register({
+    constructor: MaterialBasic,
+    classAsString: 'MaterialBasic',
+    cssClass: 'mdl-js-basic'
+  });
+})();
diff --git a/node_modules/mdl-ext/src/demo/etc/mdl-iframe-loader.js b/node_modules/mdl-ext/src/demo/etc/mdl-iframe-loader.js
new file mode 100644
index 0000000..abade92
--- /dev/null
+++ b/node_modules/mdl-ext/src/demo/etc/mdl-iframe-loader.js
@@ -0,0 +1,100 @@
+'use strict';
+
+/**
+ * Inject required CSS and JS into html fragment loaded into an <iframe>
+ * @type {{}}
+ */
+var mdlIframeLoader = {};
+(function(self) {
+
+  // The CSS and JS needed to run MDL snippets in an <iframe>
+
+  // https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent/CustomEvent
+  try {
+    new window.CustomEvent('test');
+  } catch(e) {
+    var CustomEvent = function(event, params) {
+      var evt;
+      params = params || {
+        bubbles: false,
+        cancelable: false,
+        detail: undefined
+      };
+
+      evt = document.createEvent('CustomEvent');
+      evt.initCustomEvent(event, params.bubbles, params.cancelable, params.detail);
+      return evt;
+    };
+
+    CustomEvent.prototype = window.Event.prototype;
+    window.CustomEvent = CustomEvent; // expose definition to window
+  }
+
+  var docs = [
+    { 'type': 'css', 'id': 'font-roboto-css',     'src': 'https://fonts.googleapis.com/css?family=Roboto:regular,bold,italic,thin,light,bolditalic,black,medium&amp;lang=en' },
+    { 'type': 'css', 'id': 'material-icon-css',   'src': 'https://fonts.googleapis.com/icon?family=Material+Icons' },
+    { 'type': 'css', 'id': 'dialog-polyfill-css', 'src': 'demo/styles/dialog-polyfill.css' },
+    { 'type': 'css', 'id': 'material-css',        'src': 'https://code.getmdl.io/1.1.3/material.grey-orange.min.css' },
+    { 'type': 'css', 'id': 'mdlext-css',          'src': 'lib/mdl-ext-eqjs.css' },
+    { 'type': 'css', 'id': 'demo-css',            'src': 'demo/styles/demo.css' },
+    { 'type': 'js',  'id': 'dialog-polyfill-js',  'src': 'demo/scripts/dialog-polyfill.js' },
+    { 'type': 'js',  'id': 'material-js',         'src': 'https://code.getmdl.io/1.1.3/material.min.js' },
+    { 'type': 'js',  'id': 'eq-js',               'src': 'demo/scripts/eq.min.js' },
+    { 'type': 'js',  'id': 'mdlext-js',           'src': 'lib/index.js' }
+  ];
+
+  var joinOrigin = function(origin, src) {
+    return src.startsWith('http') ? src : origin.concat(src);
+  };
+
+  var loadResources = function( origin, loadCompleted ) {
+    var expectToLoad = docs.length;
+    var filesLoaded = 0;
+
+    for (var i = 0; i < docs.length; i++) {
+      if (document.getElementById(docs[i].id) === null) {
+        var el;
+        var src = joinOrigin(origin, docs[i].src);
+
+        if (docs[i].type === 'css') {
+          el = document.createElement('link');
+          el.href = src;
+          el.rel = 'stylesheet';
+          el.type = 'text/css';
+        }
+        else {
+          el = document.createElement('script');
+          el.src = src;
+          el.type = 'text/javascript';
+          el.async = false;
+          el.charset = 'utf-8';
+        }
+        el.id = docs[i].id;
+        el.onload = function () {
+          filesLoaded++;
+          if(filesLoaded >= expectToLoad) {
+            loadCompleted();
+          }
+        };
+        document.head.appendChild(el);
+      }
+      else {
+        expectToLoad--;
+      }
+    }
+  };
+
+  /**
+   * Inject required CSS and JS into html fragment loaded into an <iframe>
+   * @param origin path relative to root of this project, e.g. "../../../
+   */
+  self.load = function( origin ) {
+    loadResources( origin, function () {
+      if(window.componentHandler) {
+        window.componentHandler.upgradeDom();
+      }
+    });
+  };
+
+  return self;
+})(mdlIframeLoader);
diff --git a/node_modules/mdl-ext/src/demo/formatfield.html b/node_modules/mdl-ext/src/demo/formatfield.html
new file mode 100644
index 0000000..8e55b6a
--- /dev/null
+++ b/node_modules/mdl-ext/src/demo/formatfield.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <include src="include/_head.html"></include>
+  <title>Material Design Lite Extensions - Format Field</title>
+</head>
+<body>
+<div class="mdl-layout mdl-js-layout mdl-layout--fixed-drawer mdl-layout--fixed-header">
+  <include src="include/_header.html"></include>
+  <include src="include/_drawer.html"></include>
+  <main id="mount" class="mdl-layout__content">
+    <include src="../../src/formatfield/snippets/formatfield.html"></include>
+  </main>
+</div>
+<include src="include/_scripts.html"></include>
+<script>
+  (function() {
+    'use strict';
+    document.addEventListener('DOMContentLoaded', function() {
+      var title = document.querySelector('#header-title');
+      if(title) {
+        title.innerHTML = 'Formatted Fields';
+      }
+    });
+  }());
+</script>
+</body>
+</html>
diff --git a/node_modules/mdl-ext/src/demo/grid.html b/node_modules/mdl-ext/src/demo/grid.html
new file mode 100644
index 0000000..1336b07
--- /dev/null
+++ b/node_modules/mdl-ext/src/demo/grid.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <include src="include/_head.html"></include>
+  <title>Material Design Lite Extensions - Grid</title>
+</head>
+<body>
+<div class="mdl-layout mdl-js-layout mdl-layout--fixed-drawer mdl-layout--fixed-header">
+  <include src="include/_header.html"></include>
+  <include src="include/_drawer.html"></include>
+  <main id="mount" class="mdl-layout__content">
+    <include src="../../src/grid/snippets/grid.html"></include>
+  </main>
+</div>
+<include src="include/_scripts.html"></include>
+<script>
+  (function() {
+    'use strict';
+    document.addEventListener('DOMContentLoaded', function() {
+      var title = document.querySelector('#header-title');
+      if(title) {
+        title.innerHTML = 'Grid';
+      }
+    });
+  }());
+</script>
+
+</body>
+</html>
diff --git a/node_modules/mdl-ext/src/demo/include/_drawer.html b/node_modules/mdl-ext/src/demo/include/_drawer.html
new file mode 100644
index 0000000..b6bafd4
--- /dev/null
+++ b/node_modules/mdl-ext/src/demo/include/_drawer.html
@@ -0,0 +1,81 @@
+<style>
+  /* Ugly CSS! Only for demo. */
+
+  #demo-drawer-accordion {
+    height: 100%;
+  }
+
+  #demo-drawer-accordion .mdlext-accordion__tab {
+    height: 64px;
+    min-height: 64px;
+    min-width: 64px;
+    padding-left: 16px;
+  }
+
+  .is-small-screen #demo-drawer-accordion .mdlext-accordion__tab {
+    height: 56px;
+    min-height: 56px;
+    min-width: 56px;
+  }
+
+  #demo-drawer-accordion .mdlext-accordion__tabpanel,
+  #demo-drawer-accordion .mdlext-accordion__tabpanel nav {
+    padding: 0;
+  }
+
+  #demo-drawer-accordion .mdlext-accordion__tabpanel .mdl-navigation__link {
+    color: rgba(255, 255, 255, 0.87);
+  }
+
+  #demo-drawer-accordion .mdlext-accordion__tabpanel .mdl-navigation__link:hover {
+    background-color: #212121;
+  }
+
+</style>
+
+
+<aside class="mdl-layout__drawer">
+
+  <ul id="demo-drawer-accordion"
+      class="mdlext-accordion mdlext-js-accordion mdlext-accordion--vertical mdlext-js-ripple-effect mdlext-js-animation-effect mdlext-dark-color-theme"
+      aria-multiselectable="false">
+
+    <li class="mdlext-accordion__panel">
+      <header class="mdlext-accordion__tab" aria-expanded="true">
+        <span class="mdlext-accordion__tab__caption">MDL Extensions</span>
+        <i class="mdlext-aria-toggle-material-icons"></i>
+      </header>
+      <section class="mdlext-accordion__tabpanel">
+        <nav class="mdl-navigation">
+          <a class="mdl-navigation__link" href="accordion.html">Accordion</a>
+          <a class="mdl-navigation__link" href="bordered-fields.html">Bordered Fields</a>
+          <a class="mdl-navigation__link" href="collapsible.html">Collapsible</a>
+          <a class="mdl-navigation__link" href="color-themes.html">Color Themes</a>
+          <a class="mdl-navigation__link" href="formatfield.html">Formatted Fields</a>
+          <a class="mdl-navigation__link" href="grid.html">Grid</a>
+          <a class="mdl-navigation__link" href="carousel.html">Image Carousel</a>
+          <a class="mdl-navigation__link" href="lightboard.html">Lightboard</a>
+          <a class="mdl-navigation__link" href="lightbox.html">Lightbox</a>
+          <a class="mdl-navigation__link" href="menu-button.html">Menu Button</a>
+          <a class="mdl-navigation__link" href="selectfield.html">Selectfield</a>
+        </nav>
+      </section>
+    </li>
+    <li class="mdlext-accordion__panel">
+      <header class="mdlext-accordion__tab">
+        <span class="mdlext-accordion__tab__caption">Sticky headers</span>
+        <i class="mdlext-aria-toggle-material-icons"></i>
+      </header>
+      <section class="mdlext-accordion__tabpanel">
+        <nav class="mdl-navigation">
+          <a class="mdl-navigation__link" href="sticky-header.html">Sticky Header I</a>
+          <a class="mdl-navigation__link" href="sticky-header-ii.html">Sticky Header II</a>
+          <a class="mdl-navigation__link" href="sticky-header-iii.html">Sticky Header III</a>
+          <a class="mdl-navigation__link" href="sticky-header-iv.html">Sticky Header IV</a>
+          <a class="mdl-navigation__link" href="sticky-header-v.html">Sticky Header V</a>
+          <a class="mdl-navigation__link" href="sticky-header-vi.html">Sticky Header VI</a>
+        </nav>
+      </section>
+    </li>
+  </ul>
+</aside>
diff --git a/node_modules/mdl-ext/src/demo/include/_head.html b/node_modules/mdl-ext/src/demo/include/_head.html
new file mode 100644
index 0000000..1f582ce
--- /dev/null
+++ b/node_modules/mdl-ext/src/demo/include/_head.html
@@ -0,0 +1,26 @@
+<meta charset="utf-8">
+<meta http-equiv="X-UA-Compatible" content="IE=edge">
+<meta name="description" content="A front-end template that helps you build fast, modern mobile web apps.">
+<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0">
+<title>Material Design Lite Extensions</title>
+
+<!-- Fallback to homescreen for Chrome <39 on Android -->
+<meta name="mobile-web-app-capable" content="yes">
+<meta name="application-name" content="Material Design Lite Extensions">
+<link rel="icon" sizes="192x192" href="./assets/android-desktop.png">
+
+<!-- Add to homescreen for Safari on iOS -->
+<meta name="apple-mobile-web-app-capable" content="yes">
+<meta name="apple-mobile-web-app-status-bar-style" content="black">
+<meta name="apple-mobile-web-app-title" content="Material Design Lite Extensions">
+<link rel="apple-touch-icon" href="./assets/ios-desktop.png">
+
+<link rel="shortcut icon" href="./assets/favicon.png">
+
+<!-- styles -->
+<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:regular,bold,italic,thin,light,bolditalic,black,medium&amp;lang=en">
+<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
+<link rel="stylesheet" href="styles/dialog-polyfill.css">
+<link rel="stylesheet" href="https://code.getmdl.io/1.3.0/material.indigo-pink.min.css">
+<link rel="stylesheet" href="../lib/mdl-ext-eqjs.min.css">
+<link rel="stylesheet" href="./styles/demo.css">
diff --git a/node_modules/mdl-ext/src/demo/include/_header-row.html b/node_modules/mdl-ext/src/demo/include/_header-row.html
new file mode 100644
index 0000000..4bd3add
--- /dev/null
+++ b/node_modules/mdl-ext/src/demo/include/_header-row.html
@@ -0,0 +1,24 @@
+<div class="mdl-layout__header-row">
+
+  <!-- Title -->
+  <span id="header-title" class="mdl-layout-title">Title goes here</span>
+
+  <!-- Add spacer, to align navigation to the right -->
+  <div class="mdl-layout-spacer"></div>
+
+  <label id="go-home" class="mdl-button mdl-js-button mdl-button--icon mdl-button--colored">
+    <a href="index.html">
+      <i class="material-icons">home</i>
+    </a>
+  </label>
+
+  <button id="header-menu" class="mdl-button mdl-js-button mdl-button--icon">
+    <i class="material-icons">more_vert</i>
+  </button>
+  <ul class="mdl-menu mdl-menu--bottom-right mdl-js-menu mdl-js-ripple-effect" for="header-menu">
+    <li class="mdl-menu__item">Some Action</li>
+    <li class="mdl-menu__item">Another Action</li>
+    <li disabled class="mdl-menu__item">Disabled Action</li>
+    <li class="mdl-menu__item">Yet Another Action</li>
+  </ul>
+</div>
diff --git a/node_modules/mdl-ext/src/demo/include/_header.html b/node_modules/mdl-ext/src/demo/include/_header.html
new file mode 100644
index 0000000..b11f9bf
--- /dev/null
+++ b/node_modules/mdl-ext/src/demo/include/_header.html
@@ -0,0 +1,3 @@
+<header class="mdl-layout__header mdlext-layout__sticky-header mdlext-js-sticky-header">
+  <include src="include/_header-row.html"></include>
+</header>
diff --git a/node_modules/mdl-ext/src/demo/include/_index.html b/node_modules/mdl-ext/src/demo/include/_index.html
new file mode 100644
index 0000000..1945e28
--- /dev/null
+++ b/node_modules/mdl-ext/src/demo/include/_index.html
@@ -0,0 +1,54 @@
+<h5 class="mdlext-demo-header">mdl-ext</h5>
+<p>Material Design Lite Ext (MDLEXT).
+  Components built with the
+  <a href="https://github.com/google/material-design-lite">Google Material Design Lite</a>
+  framework.
+</p>
+
+<h3>Components provided</h3>
+
+<h4>Accordion</h4>
+<p>A WAI-ARIA friendly accordion component with vertcial or horizontal layout.</p>
+
+<h4>Bordered Fields</h4>
+<p>The Material Design Lite Ext (MDLEXT) bordered fieldscomponent demonstrates
+  how you can create your own theme of MDL text fields.
+</p>
+
+<h4>Collapsible</h4>
+<p>A collapsible is a component to mark expandable and collapsible regions.</p>
+
+<h4>Color Themes</h4>
+<p>MDL provides only one color theme. Many designs require more than one theme, e.g. a dark theme and a light theme.</p>
+
+<h4>Grid</h4>
+<p>A responsive grid based on element queries in favour of media queries.</p>
+
+<h4>Image Carousel</h4>
+<p>A responsive, WAI-ARIA friendly, image carousel.</p>
+
+<h4>Lightboard</h4>
+<p>A lightboard is a translucent surface illuminated from behind, used for
+  situations where a shape laid upon the surface needs to be seen with high contrast.
+  In the "old days" of photography photograpers used a lightboard to get a quick
+  view of, sorting and organizing their slides.
+</p>
+
+<h4>Lightbox</h4>
+<p>A lightbox displays an image filling the screen, and dimming out the rest of
+  the web page. It acts as a modal dialog using the <code>&lt;dialog&gt;</code>
+  element as a container for the lightbox.
+</p>
+
+<h4>Menu Button</h4>
+<p>A WAI-ARIA friendly menu button component/widget with roles, attributes and behavior in accordance with the
+  specification given in WAI-ARIA Authoring Practices, section 2.20.
+</p>
+
+<h4>Selectfield</h4>
+<p>The Material Design Lite Ext (MDLEXT) select field component is an enhanced version
+  of the standard [HTML <code>&lt;select&gt;</code> element.
+</p>
+
+<h4>Sticky Header</h4>
+<p>A sticky header makes site navigation easily accessible anywhere on the page and saves content space at the same.</p>
diff --git a/node_modules/mdl-ext/src/demo/include/_interactive-body-filler.html b/node_modules/mdl-ext/src/demo/include/_interactive-body-filler.html
new file mode 100644
index 0000000..e8103c1
--- /dev/null
+++ b/node_modules/mdl-ext/src/demo/include/_interactive-body-filler.html
@@ -0,0 +1,52 @@
+<script>
+  (function() {
+    'use strict';
+    document.addEventListener('DOMContentLoaded', function() {
+      var title = document.querySelector('#header-title');
+      if(title) {
+        title.innerHTML = 'Sticky Header';
+      }
+    });
+
+    var btn = document.querySelector('#a-button');
+    btn.addEventListener('click', function() {
+
+      var content = document.querySelector('.mdl-layout__content');
+      content.insertAdjacentHTML('beforeend',
+        '<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. In porttitor lorem eu faucibus aliquet. ' +
+        'In vehicula risus turpis, ut dictum ante tristique et. Aenean ultricies sed urna ac condimentum. ' +
+        'Vivamus nisl tortor, ultricies at aliquam nec, semper at purus. Duis purus tortor, laoreet eget ante a, ' +
+        'rhoncus vulputate lorem. Pellentesque id enim ut massa posuere vestibulum sit amet eget elit. Nulla quis ' +
+        'euismod massa, id varius dui. Ut congue urna non ipsum placerat rhoncus. Curabitur a sollicitudin diam. ' +
+        'Donec id lectus eleifend, blandit magna a, mattis turpis. Fusce non tellus pulvinar, finibus dui ac, ' +
+        'porttitor ante. Vestibulum et commodo purus, et tincidunt nulla. Suspendisse blandit sodales est, nec ' +
+        'luctus sem sollicitudin in. Etiam libero tellus, porttitor sit amet velit a, commodo sodales neque.</p>' +
+        '<p>Maecenas id sodales lacus, eu ullamcorper nibh. Sed posuere consectetur nunc nec dapibus. Nam tristique ' +
+        'ex vel urna dapibus luctus. Phasellus eget mi ac tortor aliquet auctor non vitae risus. Cum sociis natoque ' +
+        'penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec et egestas elit. Sed id lorem enim.' +
+        'Aliquam maximus enim sed tincidunt pretium.</p>' +
+        '<p>Phasellus dictum, leo vel bibendum efficitur, mauris metus volutpat magna, at pharetra libero dolor id ' +
+        'tellus. Mauris convallis tempus libero, sit amet suscipit massa maximus a. Duis ut dignissim nulla, nec ' +
+        'gravida purus. Proin eget erat justo. Phasellus congue sapien eleifend sapien mollis, nec molestie eros ' +
+        'efficitur. Pellentesque et diam at risus ultrices pharetra nec in augue. Phasellus vestibulum, lacus a ' +
+        'dictum vulputate, mauris nisi dictum massa, in venenatis felis sapien a nunc. Integer mi tellus, imperdiet ' +
+        'vel dignissim sed, fringilla ut urna.</p>' +
+        '<p>Suspendisse potenti. Pellentesque eget suscipit orci, at tempor est. Cras sed sollicitudin nunc. Donec ' +
+        'convallis, arcu a euismod cursus, arcu odio pharetra lectus, vitae feugiat diam massa vestibulum metus. In ' +
+        'odio tellus, consectetur eget est et, vehicula hendrerit dolor. Ut ultrices nulla tellus, sit amet ' +
+        'consectetur dolor aliquet quis. Etiam non fermentum dolor.</p>' +
+        '<p>Donec accumsan risus in lectus sollicitudin ' +
+        'vulputate. Praesent condimentum a leo at interdum. Donec ' +
+        'pharetra congue erat a accumsan. Aliquam gravida ' +
+        'lobortis mi, id elementum sapien ultrices vel. ' +
+        'Pellentesque habitant morbi tristique senectus et ' +
+        'netus et malesuada fames ac turpis egestas. Proin ' +
+        'consequat enim orci, nec blandit lorem luctus ut. ' +
+        'Lorem ipsum dolor sit amet, consectetur adipiscing elit. ' +
+        'Etiam pretium nunc non metus gravida, nec tincidunt ' +
+        'tortor volutpat. Aliquam erat volutpat. Curabitur ' +
+        'varius purus ac auctor pharetra.</p>');
+    });
+
+  }());
+</script>
diff --git a/node_modules/mdl-ext/src/demo/include/_scripts.html b/node_modules/mdl-ext/src/demo/include/_scripts.html
new file mode 100644
index 0000000..97011e6
--- /dev/null
+++ b/node_modules/mdl-ext/src/demo/include/_scripts.html
@@ -0,0 +1,5 @@
+<script src="scripts/dialog-polyfill.js" type="text/javascript" charset="utf-8"></script>
+<script src="https://cdn.polyfill.io/v2/polyfill.min.js?features=default,es6"></script>
+<script src="scripts/eq.min.js" type="text/javascript" charset="utf-8"></script>
+<script src="https://code.getmdl.io/1.2.1/material.min.js" type="text/javascript" charset="utf-8"></script>
+<script src="../lib/mdl-ext.min.js" type="text/javascript" charset="utf-8"></script>
diff --git a/node_modules/mdl-ext/src/demo/index.html b/node_modules/mdl-ext/src/demo/index.html
new file mode 100644
index 0000000..3aa4e01
--- /dev/null
+++ b/node_modules/mdl-ext/src/demo/index.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <include src="include/_head.html"></include>
+  <title>Material Design Lite Extensions</title>
+</head>
+
+<body>
+<div class="mdl-layout mdl-js-layout mdl-layout--fixed-drawer mdl-layout--fixed-header">
+  <include src="include/_header.html"></include>
+  <include src="include/_drawer.html"></include>
+  <main id="mount" class="mdl-layout__content">
+    <include src="include/_index.html"></include>
+  </main>
+</div>
+<include src="include/_scripts.html"></include>
+<script>
+  (function() {
+    'use strict';
+    document.addEventListener('DOMContentLoaded', function() {
+      var title = document.querySelector('#header-title');
+      if(title) {
+        title.innerHTML = 'Material Design Lite Extensions';
+      }
+    });
+  }());
+</script>
+</body>
+</html>
diff --git a/node_modules/mdl-ext/src/demo/lightboard.html b/node_modules/mdl-ext/src/demo/lightboard.html
new file mode 100644
index 0000000..93adf1c
--- /dev/null
+++ b/node_modules/mdl-ext/src/demo/lightboard.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <include src="include/_head.html"></include>
+  <title>Material Design Lite Extensions - Lightboard</title>
+</head>
+<body>
+<div class="mdl-layout mdl-js-layout mdl-layout--fixed-drawer mdl-layout--fixed-header">
+  <include src="include/_header.html"></include>
+  <include src="include/_drawer.html"></include>
+  <main id="mount" class="mdl-layout__content">
+    <include src="../../src/lightboard/snippets/lightboard.html"></include>
+  </main>
+</div>
+<include src="include/_scripts.html"></include>
+<script>
+  (function() {
+    'use strict';
+    document.addEventListener('DOMContentLoaded', function() {
+      var title = document.querySelector('#header-title');
+      if(title) {
+        title.innerHTML = 'Lightboard';
+      }
+    });
+  }());
+</script>
+</body>
+</html>
diff --git a/node_modules/mdl-ext/src/demo/lightbox.html b/node_modules/mdl-ext/src/demo/lightbox.html
new file mode 100644
index 0000000..6b774bf
--- /dev/null
+++ b/node_modules/mdl-ext/src/demo/lightbox.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <include src="include/_head.html"></include>
+  <title>Material Design Lite Extensions - Lightbox</title>
+</head>
+<body>
+<div class="mdl-layout mdl-js-layout mdl-layout--fixed-drawer mdl-layout--fixed-header">
+  <include src="include/_header.html"></include>
+  <include src="include/_drawer.html"></include>
+  <main id="mount" class="mdl-layout__content">
+    <include src="../../src/lightbox/snippets/lightbox.html"></include>
+  </main>
+</div>
+<include src="include/_scripts.html"></include>
+<script>
+  (function() {
+    'use strict';
+    document.addEventListener('DOMContentLoaded', function() {
+      var title = document.querySelector('#header-title');
+      if(title) {
+        title.innerHTML = 'Lightbox';
+      }
+    });
+  }());
+</script>
+</body>
+</html>
diff --git a/node_modules/mdl-ext/src/demo/menu-button.html b/node_modules/mdl-ext/src/demo/menu-button.html
new file mode 100644
index 0000000..0ea10e4
--- /dev/null
+++ b/node_modules/mdl-ext/src/demo/menu-button.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <include src="include/_head.html"></include>
+  <title>Material Design Lite Extensions - Menu Button</title>
+</head>
+<body>
+<div class="mdl-layout mdl-js-layout mdl-layout--fixed-drawer mdl-layout--fixed-header">
+  <include src="include/_header.html"></include>
+  <include src="include/_drawer.html"></include>
+  <main id="mount" class="mdl-layout__content">
+    <include src="../../src/menu-button/snippets/menu-button.html"></include>
+  </main>
+</div>
+<include src="include/_scripts.html"></include>
+<script>
+  (function() {
+    'use strict';
+    document.addEventListener('DOMContentLoaded', function() {
+      var title = document.querySelector('#header-title');
+      if(title) {
+        title.innerHTML = 'Menu Button';
+      }
+    });
+  }());
+</script>
+</body>
+</html>
diff --git a/node_modules/mdl-ext/src/demo/resize-observer.html b/node_modules/mdl-ext/src/demo/resize-observer.html
new file mode 100644
index 0000000..905db53
--- /dev/null
+++ b/node_modules/mdl-ext/src/demo/resize-observer.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <include src="include/_head.html"></include>
+  <title>Material Design Lite Extensions - Resize Observer</title>
+</head>
+<body>
+<div class="mdl-layout mdl-js-layout mdl-layout--fixed-drawer mdl-layout--fixed-header">
+  <include src="include/_header.html"></include>
+  <include src="include/_drawer.html"></include>
+  <main id="mount" class="mdl-layout__content">
+    <include src="../../src/utils/snippets/resize-observer.html"></include>
+  </main>
+</div>
+<include src="include/_scripts.html"></include>
+<script>
+  (function() {
+    'use strict';
+    document.addEventListener('DOMContentLoaded', function() {
+      var title = document.querySelector('#header-title');
+      if(title) {
+        title.innerHTML = 'Resize Observer';
+      }
+    });
+  }());
+</script>
+</body>
+</html>
diff --git a/node_modules/mdl-ext/src/demo/selectfield.html b/node_modules/mdl-ext/src/demo/selectfield.html
new file mode 100644
index 0000000..089b5d9
--- /dev/null
+++ b/node_modules/mdl-ext/src/demo/selectfield.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <include src="include/_head.html"></include>
+  <title>Material Design Lite Extensions - Selectfield</title>
+</head>
+<body>
+<div class="mdl-layout mdl-js-layout mdl-layout--fixed-drawer mdl-layout--fixed-header">
+  <include src="include/_header.html"></include>
+  <include src="include/_drawer.html"></include>
+  <main id="mount" class="mdl-layout__content">
+    <include src="../../src/selectfield/snippets/selectfield.html"></include>
+  </main>
+</div>
+<include src="include/_scripts.html"></include>
+<script>
+  (function() {
+    'use strict';
+    document.addEventListener('DOMContentLoaded', function() {
+      var title = document.querySelector('#header-title');
+      if(title) {
+        title.innerHTML = 'Selectfield';
+      }
+    });
+  }());
+</script>
+</body>
+</html>
diff --git a/node_modules/mdl-ext/src/demo/sticky-header-ii.html b/node_modules/mdl-ext/src/demo/sticky-header-ii.html
new file mode 100644
index 0000000..794c54e
--- /dev/null
+++ b/node_modules/mdl-ext/src/demo/sticky-header-ii.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <include src="include/_head.html"></include>
+  <title>Material Design Lite Extensions - Sticky Header</title>
+</head>
+
+<body>
+<div class="mdl-layout mdl-js-layout mdl-layout--fixed-header">
+
+  <include src="include/_header.html"></include>
+  <include src="include/_drawer.html"></include>
+
+  <main id="mount" class="mdl-layout__content">
+
+    <h5>Sticky Header, Drawer (not fixed)</h5>
+
+    <p>A sticky header makes site navigation easily accessible anywhere on the page and saves content space at the same.</p>
+    <p>The header should auto-hide, i.e. hiding the header automatically when a user starts scrolling down the page
+      and bringing the header back when a user might need it: they reach the bottom of the page or start scrolling up.</p>
+    <p class="mdl-typography--subhead">To see how the sticky header works, click the button a few
+      times to add content. Next scroll the page up and down.</p>
+    <button id="a-button" class="mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect mdl-button--accent">
+      Click to add more content
+    </button>
+  </main>
+</div>
+<include src="include/_scripts.html"></include>
+<include src="include/_interactive-body-filler.html"></include>
+</body>
+</html>
diff --git a/node_modules/mdl-ext/src/demo/sticky-header-iii.html b/node_modules/mdl-ext/src/demo/sticky-header-iii.html
new file mode 100644
index 0000000..e6da56b
--- /dev/null
+++ b/node_modules/mdl-ext/src/demo/sticky-header-iii.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <include src="include/_head.html"></include>
+  <title>Material Design Lite Extensions - Sticky Header</title>
+</head>
+
+<body>
+<div class="mdl-layout mdl-js-layout mdl-layout--fixed-header">
+
+  <include src="include/_header.html"></include>
+
+  <main id="mount" class="mdl-layout__content">
+
+    <h5>Sticky Header, No Drawer</h5>
+
+    <p>A sticky header makes site navigation easily accessible anywhere on the page and saves content space at the same.</p>
+    <p>The header should auto-hide, i.e. hiding the header automatically when a user starts scrolling down the page
+      and bringing the header back when a user might need it: they reach the bottom of the page or start scrolling up.</p>
+    <p class="mdl-typography--subhead">To see how the sticky header works, click the button a few
+      times to add content. Next scroll the page up and down.</p>
+    <button id="a-button" class="mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect mdl-button--accent">
+      Click to add more content
+    </button>
+  </main>
+</div>
+<include src="include/_scripts.html"></include>
+<include src="include/_interactive-body-filler.html"></include>
+</body>
+</html>
diff --git a/node_modules/mdl-ext/src/demo/sticky-header-iv.html b/node_modules/mdl-ext/src/demo/sticky-header-iv.html
new file mode 100644
index 0000000..2b91ae3
--- /dev/null
+++ b/node_modules/mdl-ext/src/demo/sticky-header-iv.html
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <include src="include/_head.html"></include>
+  <title>Material Design Lite Extensions - Sticky Header</title>
+</head>
+
+<body>
+<div class="mdl-layout mdl-js-layout mdl-layout--fixed-drawer mdl-layout--fixed-header">
+
+  <header class="mdl-layout__header mdl-layout__header--waterfall mdlext-layout__sticky-header mdlext-js-sticky-header">
+    <include src="include/_header-row.html"></include>
+
+    <div class="mdl-layout__header-row">
+      <div class="mdl-layout-spacer"></div>
+      <nav class="mdl-navigation">
+        <a class="mdl-navigation__link" href="">Link</a>
+        <a class="mdl-navigation__link" href="">Link</a>
+        <a class="mdl-navigation__link" href="">Link</a>
+        <a class="mdl-navigation__link" href="">Link</a>
+      </nav>
+    </div>
+  </header>
+
+  <include src="include/_drawer.html"></include>
+
+  <main id="mount" class="mdl-layout__content">
+
+    <h5>Sticky Header, Waterfall, Fixed Drawer</h5>
+
+    <p>A sticky header makes site navigation easily accessible anywhere on the page and saves content space at the same.</p>
+    <p>The header should auto-hide, i.e. hiding the header automatically when a user starts scrolling down the page
+      and bringing the header back when a user might need it: they reach the bottom of the page or start scrolling up.</p>
+    <p class="mdl-typography--subhead">To see how the sticky header works, click the button a few
+      times to add content. Next scroll the page up and down.</p>
+    <button id="a-button" class="mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect mdl-button--accent">
+      Click to add more content
+    </button>
+  </main>
+</div>
+<include src="include/_scripts.html"></include>
+<include src="include/_interactive-body-filler.html"></include>
+</body>
+</html>
diff --git a/node_modules/mdl-ext/src/demo/sticky-header-v.html b/node_modules/mdl-ext/src/demo/sticky-header-v.html
new file mode 100644
index 0000000..99027e4
--- /dev/null
+++ b/node_modules/mdl-ext/src/demo/sticky-header-v.html
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <include src="include/_head.html"></include>
+  <title>Material Design Lite Extensions - Sticky Header</title>
+</head>
+
+<body>
+<div class="mdl-layout mdl-js-layout mdl-layout--fixed-header">
+
+  <header class="mdl-layout__header mdl-layout__header--waterfall mdlext-layout__sticky-header mdlext-js-sticky-header">
+    <include src="include/_header-row.html"></include>
+
+    <div class="mdl-layout__header-row">
+      <div class="mdl-layout-spacer"></div>
+      <nav class="mdl-navigation">
+        <a class="mdl-navigation__link" href="">Link</a>
+        <a class="mdl-navigation__link" href="">Link</a>
+        <a class="mdl-navigation__link" href="">Link</a>
+        <a class="mdl-navigation__link" href="">Link</a>
+      </nav>
+    </div>
+  </header>
+
+  <include src="include/_drawer.html"></include>
+
+  <main id="mount" class="mdl-layout__content">
+
+    <h5>Sticky Header, Waterfall, Drawer (not fixed)</h5>
+
+    <p>A sticky header makes site navigation easily accessible anywhere on the page and saves content space at the same.</p>
+    <p>The header should auto-hide, i.e. hiding the header automatically when a user starts scrolling down the page
+      and bringing the header back when a user might need it: they reach the bottom of the page or start scrolling up.</p>
+    <p class="mdl-typography--subhead">To see how the sticky header works, click the button a few
+      times to add content. Next scroll the page up and down.</p>
+    <button id="a-button" class="mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect mdl-button--accent">
+      Click to add more content
+    </button>
+  </main>
+</div>
+<include src="include/_scripts.html"></include>
+<include src="include/_interactive-body-filler.html"></include>
+</body>
+</html>
diff --git a/node_modules/mdl-ext/src/demo/sticky-header-vi.html b/node_modules/mdl-ext/src/demo/sticky-header-vi.html
new file mode 100644
index 0000000..840b8bc
--- /dev/null
+++ b/node_modules/mdl-ext/src/demo/sticky-header-vi.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <include src="include/_head.html"></include>
+  <title>Material Design Lite Extensions - Sticky Header</title>
+</head>
+
+<body>
+<div class="mdl-layout mdl-js-layout mdl-layout--fixed-header">
+
+  <header class="mdl-layout__header mdl-layout__header--waterfall mdlext-layout__sticky-header mdlext-js-sticky-header">
+    <include src="include/_header-row.html"></include>
+
+    <div class="mdl-layout__header-row">
+      <div class="mdl-layout-spacer"></div>
+      <nav class="mdl-navigation">
+        <a class="mdl-navigation__link" href="">Link</a>
+        <a class="mdl-navigation__link" href="">Link</a>
+        <a class="mdl-navigation__link" href="">Link</a>
+        <a class="mdl-navigation__link" href="">Link</a>
+      </nav>
+    </div>
+  </header>
+
+  <main id="mount" class="mdl-layout__content">
+
+    <h5>Sticky Header, Waterfall, No Drawer</h5>
+
+    <p>A sticky header makes site navigation easily accessible anywhere on the page and saves content space at the same.</p>
+    <p>The header should auto-hide, i.e. hiding the header automatically when a user starts scrolling down the page
+      and bringing the header back when a user might need it: they reach the bottom of the page or start scrolling up.</p>
+    <p class="mdl-typography--subhead">To see how the sticky header works, click the button a few
+      times to add content. Next scroll the page up and down.</p>
+    <button id="a-button" class="mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect mdl-button--accent">
+      Click to add more content
+    </button>
+  </main>
+</div>
+<include src="include/_scripts.html"></include>
+<include src="include/_interactive-body-filler.html"></include>
+</body>
+</html>
diff --git a/node_modules/mdl-ext/src/demo/sticky-header.html b/node_modules/mdl-ext/src/demo/sticky-header.html
new file mode 100644
index 0000000..6e7080a
--- /dev/null
+++ b/node_modules/mdl-ext/src/demo/sticky-header.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <include src="include/_head.html"></include>
+  <title>Material Design Lite Extensions - Sticky Header</title>
+</head>
+
+<body>
+<div class="mdl-layout mdl-js-layout mdl-layout--fixed-drawer mdl-layout--fixed-header">
+  <include src="include/_header.html"></include>
+  <include src="include/_drawer.html"></include>
+  <main id="mount" class="mdl-layout__content">
+
+    <h5>Sticky Header, Fixed Drawer Example</h5>
+
+    <p>A sticky header makes site navigation easily accessible anywhere on the page and saves content space at the same.</p>
+    <p>The header should auto-hide, i.e. hiding the header automatically when a user starts scrolling down the page
+      and bringing the header back when a user might need it: they reach the bottom of the page or start scrolling up.</p>
+    <p class="mdl-typography--subhead">To see how the sticky header works, click the button a few
+      times to add content. Next scroll the page up and down.</p>
+    <button id="a-button" class="mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect mdl-button--accent">
+      Click to add more content
+    </button>
+  </main>
+</div>
+<include src="include/_scripts.html"></include>
+<include src="include/_interactive-body-filler.html"></include>
+</body>
+</html>
diff --git a/node_modules/mdl-ext/src/demo/styles/demo.css b/node_modules/mdl-ext/src/demo/styles/demo.css
new file mode 100644
index 0000000..28151ef
--- /dev/null
+++ b/node_modules/mdl-ext/src/demo/styles/demo.css
@@ -0,0 +1,69 @@
+html {
+  box-sizing: border-box;
+}
+*, *::before, *::after, input[type="search"] {
+  box-sizing: inherit;
+}
+
+body {
+  overflow: hidden; /* Needed by Chrome OSX and IOS to avoid "double" scrollbars when a menu opens */
+}
+
+#mount {
+  padding-left: 12px;
+  padding-right: 8px;
+  height:100%;
+}
+
+#mount > *:first-child:not(h5) {
+  padding-top: 16px;
+}
+
+.is-small-screen #mount {
+  padding-left: 4px;
+  padding-right: 4px;
+}
+
+/* Rules for sizing the icon */
+/* Not provided in "material-design-icons/iconfont/material-icon.css" */
+
+.material-icons.md-12 {
+   font-size: 12px;
+ }
+.material-icons.md-16 {
+  font-size: 16px;
+}
+.material-icons.md-18 {
+   font-size: 18px;
+ }
+.material-icons.md-24 {
+   font-size: 24px;
+ }
+.material-icons.md-32 {
+   font-size: 24px;
+ }
+.material-icons.md-36 {
+   font-size: 36px;
+ }
+.material-icons.md-48 {
+   font-size: 48px;
+ }
+.material-icons.md-56 {
+  font-size: 56px;
+}
+
+/* Rules for using icons as black on a light background. */
+.material-icons.md-dark {
+   color: rgba(0, 0, 0, 0.54);
+}
+.material-icons.md-dark.md-inactive {
+   color: rgba(0, 0, 0, 0.26);
+ }
+
+/* Rules for using icons as white on a dark background. */
+.material-icons.md-light {
+   color: rgba(255, 255, 255, 1);
+}
+.material-icons.md-light.md-inactive {
+   color: rgba(255, 255, 255, 0.3);
+ }
diff --git a/node_modules/mdl-ext/src/dialog/dialog.scss b/node_modules/mdl-ext/src/dialog/dialog.scss
new file mode 100644
index 0000000..fb74849
--- /dev/null
+++ b/node_modules/mdl-ext/src/dialog/dialog.scss
@@ -0,0 +1,46 @@
+/**
+ * Copyright 2015 Google Inc. All Rights Reserved.
+ * Copyright 2016 Leif Olsen. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SASS based on css from Google Chrome Dialog polyfill, https://github.com/GoogleChrome/dialog-polyfill
+ * @include 'node_modules/dialog-polyfill/dialog-polyfill.css' before using this
+ */
+
+@import "../variables";
+
+dialog.mdlext-dialog {
+  position: absolute;
+  border: 0;
+  opacity: 0;
+  padding: $mdlext-dialog-padding;
+  background-color: $mdlext-dialog-background-color;
+
+  &[open] {
+    animation: mdlext-open-dialog $mdlext-dialog-open-animation;
+  }
+  &[open]::backdrop {
+    animation: mdlext-darken-backdrop $mdlext-dialog-backdrop-animation;
+  }
+  &[open] + .backdrop {
+    animation: mdlext-darken-backdrop $mdlext-dialog-backdrop-animation;
+  }
+}
+
+@keyframes mdlext-darken-backdrop {
+  to { background: $mdlext-dialog-backdrop-color; }
+}
+@keyframes mdlext-open-dialog {
+  to { opacity: 1; }
+}
diff --git a/node_modules/mdl-ext/src/dialog/readme.md b/node_modules/mdl-ext/src/dialog/readme.md
new file mode 100644
index 0000000..5902343
--- /dev/null
+++ b/node_modules/mdl-ext/src/dialog/readme.md
@@ -0,0 +1,30 @@
+# Dialog
+Additional styling for `<dialog>`, based on the [Google Chrome Dialog polyfill](https://github.com/GoogleChrome/dialog-polyfill).
+`@include 'node_modules/dialog-polyfill/dialog-polyfill.css'` before using this in your SASS build.
+
+## Introduction
+The Material Design Lite Ext (MDLEXT) `mdlext-dialog` class provides better control of the dialog backdrop.
+
+## Basic Usage
+Refer to the [Google Chrome Dialog polyfill](https://github.com/GoogleChrome/dialog-polyfill) documentaion amd the MDLEXT [lightbox](../lightbox) component.
+ 
+## Configuration options
+
+The MDLEXT CSS classes apply various predefined visual and behavioral enhancements to the dialog. 
+The table below lists the available classes and their effects.
+
+| MDLEXT class | Effect | Remarks |
+|-----------|--------|---------|
+| `mdlext-dialog` | Defines container as an MDLEXT component | Required on `<dialog>` element |
+
+ 
+You can modify the dialog trough the following SASS variables.
+
+| SASS variable |Description | Remarks | 
+|-----------|--------|---------|
+| `$mdlext-dialog-padding` | Dialog padding | default `0` | 
+| `$mdlext-dialog-background-color` | Dialog background color | default `transparent` | 
+| `$mdlext-dialog-backdrop-color` | Backdrop color when dialog is open | default `rgba(0,0,0,0.8)` | 
+| `$mdlext-dialog-open-animation` | Animation when dialog opens | default `.5s .2s forwards` | 
+| `$mdlext-dialog-backdrop-animation` | Backdrop animation when dialog opens | default `.2s forwards` | 
+
diff --git a/node_modules/mdl-ext/src/formatfield/formatfield.js b/node_modules/mdl-ext/src/formatfield/formatfield.js
new file mode 100644
index 0000000..0b84819
--- /dev/null
+++ b/node_modules/mdl-ext/src/formatfield/formatfield.js
@@ -0,0 +1,280 @@
+/**
+ * @license
+ * Copyright 2016-2017 Leif Olsen. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * This code is built with Google Material Design Lite,
+ * which is Licensed under the Apache License, Version 2.0
+ */
+
+
+import {jsonStringToObject} from '../utils/json-utils';
+import {
+  IS_UPGRADED,
+} from '../utils/constants';
+
+const JS_FORMAT_FIELD = 'mdlext-js-formatfield';
+const FORMAT_FIELD_COMPONENT = 'MaterialExtFormatfield';
+
+/**
+ * Detect browser locale
+ * @returns {string} the locale
+ * @see http://stackoverflow.com/questions/1043339/javascript-for-detecting-browser-language-preference
+ */
+const browserLanguage = () => {
+  return navigator.languages
+    ? navigator.languages[0]
+    : navigator.language || navigator.userLanguage;
+};
+
+/**
+ * The formatfield  formats an input field  using language sensitive number formatting.
+ */
+
+class FormatField {
+  static timer = null;
+
+  element_;
+  input_;
+  options_ = {};
+  intlGroupSeparator_;
+  intlDecimalSeparator_;
+
+  constructor(element) {
+    this.element_ = element;
+    this.init();
+  }
+
+  clickHandler = () => {
+    clearTimeout(FormatField.timer);
+  };
+
+  focusInHandler = () => {
+    if(!(this.input.readOnly || this.input.disabled)) {
+      this.input.value = this.unformatInput();
+      //setTimeout(() => this.input.setSelectionRange(0, this.input.value.length), 20);
+      FormatField.timer = setTimeout(() => this.input.select(), 200);
+    }
+  };
+
+  focusOutHandler = () => {
+    clearTimeout(FormatField.timer);
+
+    if(!(this.input.readOnly || this.input.disabled)) {
+      this.formatValue();
+    }
+  };
+
+  get element() {
+    return this.element_;
+  }
+
+  get input() {
+    return this.input_;
+  }
+
+  get options() {
+    return this.options_;
+  }
+
+  stripSeparatorsFromValue() {
+    const doReplace = () => this.input.value
+      .replace(/\s/g, '')
+      .replace(new RegExp(this.options.groupSeparator, 'g'), '')
+      .replace(this.options.decimalSeparator, '.');
+      //.replace(this.intlGroupSeparator_, ''),
+      //.replace(this.intlDecimalSeparator_, '.');
+
+    return this.input.value ? doReplace() : this.input.value;
+  }
+
+  fixSeparators(value) {
+    const doReplace = () => value
+      .replace(new RegExp(this.intlGroupSeparator_, 'g'), this.options.groupSeparator)
+      .replace(this.intlDecimalSeparator_, this.options.decimalSeparator);
+
+    return value ? doReplace() : value;
+  }
+
+  formatValue() {
+    if(this.input.value) {
+      const v = new Intl.NumberFormat(this.options.locales, this.options)
+        .format(this.stripSeparatorsFromValue());
+
+      if('NaN' !== v) {
+        this.input.value = this.fixSeparators(v);
+      }
+    }
+  }
+
+  unformat() {
+    const doReplace = () => this.input.value
+      .replace(/\s/g, '')
+      .replace(new RegExp(this.options.groupSeparator, 'g'), '')
+      .replace(this.options.decimalSeparator, '.');
+
+    return this.input.value ? doReplace() : this.input.value;
+  }
+
+  unformatInput() {
+    const doReplace = () => this.input.value
+      .replace(/\s/g, '')
+      .replace(new RegExp(this.options.groupSeparator, 'g'), '');
+
+    return this.input.value ? doReplace() : this.input.value;
+  }
+
+  removeListeners() {
+    this.input.removeEventListener('click', this.clickHandler);
+    this.input.removeEventListener('focusin', this.focusInHandler);
+    this.input.removeEventListener('focusout', this.focusOutHandler);
+  }
+
+  init() {
+    const addListeners = () => {
+      this.input.addEventListener('click', this.clickHandler);
+      this.input.addEventListener('focusin', this.focusInHandler);
+      this.input.addEventListener('focusout', this.focusOutHandler);
+    };
+
+    const addOptions = () => {
+      const opts = this.element.getAttribute('data-formatfield-options') ||
+        this.input.getAttribute('data-formatfield-options');
+      if(opts) {
+        this.options_ = jsonStringToObject(opts, this.options);
+      }
+    };
+
+    const addLocale = () => {
+      if(!this.options.locales) {
+        this.options.locales = browserLanguage() || 'en-US'; //'nb-NO', //'en-US',
+      }
+    };
+
+    const addGrouping = () => {
+      const s = (1234.5).toLocaleString(this.options.locales, {
+        style: 'decimal',
+        useGrouping: true,
+        minimumFractionDigits: 1,
+        maximumFractionDigits: 1
+      });
+
+      this.intlGroupSeparator_ = s.charAt(1);
+      this.intlDecimalSeparator_ = s.charAt(s.length-2);
+      this.options.groupSeparator = this.options.groupSeparator || this.intlGroupSeparator_;
+      this.options.decimalSeparator = this.options.decimalSeparator || this.intlDecimalSeparator_;
+
+      if(this.options.groupSeparator === this.options.decimalSeparator) {
+        const e = `Error! options.groupSeparator, "${this.options.groupSeparator}" ` +
+          'and options.decimalSeparator, ' +
+          `"${this.options.decimalSeparator}" should not be equal`;
+        throw new Error(e);
+      }
+    };
+
+    this.input_ = this.element.querySelector('input') || this.element;
+
+    addOptions();
+    addLocale();
+    addGrouping();
+    this.formatValue();
+    addListeners();
+  }
+
+  downgrade() {
+    this.removeListeners();
+  }
+
+}
+
+(function() {
+  'use strict';
+
+  /**
+   * @constructor
+   * @param {HTMLElement} element The element that will be upgraded.
+   */
+  const MaterialExtFormatfield = function MaterialExtFormatfield(element) {
+    this.element_ = element;
+    this.formatField_ = null;
+
+    // Initialize instance.
+    this.init();
+  };
+  window['MaterialExtFormatfield'] = MaterialExtFormatfield;
+
+  /**
+   * Initialize component
+   */
+  MaterialExtFormatfield.prototype.init = function() {
+    if (this.element_) {
+      this.element_.classList.add(IS_UPGRADED);
+      this.formatField_ = new FormatField(this.element_);
+
+      // Listen to 'mdl-componentdowngraded' event
+      this.element_.addEventListener('mdl-componentdowngraded', this.mdlDowngrade_.bind(this));
+    }
+  };
+
+  /**
+   * Get options object
+   *
+   * @public
+   *
+   * @returns {Object} the options object
+   */
+  MaterialExtFormatfield.prototype.getOptions = function() {
+    return this.formatField_.options;
+  };
+  MaterialExtFormatfield.prototype['getOptions'] = MaterialExtFormatfield.prototype.getOptions;
+
+
+  /**
+   * A unformatted value is a string value where the locale specific decimal separator
+   * is replaced with a '.' separator and group separators are stripped.
+   * The returned value is suitable for parsing to a JavaScript numerical value.
+   *
+   * @example
+   * input.value = '1 234,5';
+   * inputElement.MaterialExtFormatfield.getUnformattedValue();
+   * // Returns '1234.5'
+   *
+   * @public
+   *
+   * @returns {String} the unformatted value
+   */
+  MaterialExtFormatfield.prototype.getUnformattedValue = function() {
+    return this.formatField_.unformat();
+  };
+  MaterialExtFormatfield.prototype['getUnformattedValue'] = MaterialExtFormatfield.prototype.getUnformattedValue;
+
+  /*
+   * Downgrade component
+   * E.g remove listeners and clean up resources
+   */
+  MaterialExtFormatfield.prototype.mdlDowngrade_ = function() {
+    this.formatField_.downgrade();
+  };
+
+  // The component registers itself. It can assume componentHandler is available
+  // in the global scope.
+  /* eslint no-undef: 0 */
+  componentHandler.register({
+    constructor: MaterialExtFormatfield,
+    classAsString: FORMAT_FIELD_COMPONENT,
+    cssClass: JS_FORMAT_FIELD,
+    widget: true
+  });
+
+})();
diff --git a/node_modules/mdl-ext/src/formatfield/readme.md b/node_modules/mdl-ext/src/formatfield/readme.md
new file mode 100644
index 0000000..c3737eb
--- /dev/null
+++ b/node_modules/mdl-ext/src/formatfield/readme.md
@@ -0,0 +1,103 @@
+#Formatfield
+![Formatfield](../../etc/formatfield.png)
+
+The formatfield component formats an input field using language sensitive 
+**number formatting**. It acts as a "pluggable" component and can be added to a 
+`mdl-textfield` component or to a `<input>` element.
+
+## To include a MDLEXT formatfield component:
+&nbsp;1. Code a [single-line `mdl-textfield`](https://getmdl.io/components/index.html#textfields-section) 
+component.
+```html
+<div class="mdl-textfield mdl-js-textfield">
+  <input class="mdl-textfield__input" type="text" 
+    pattern="-?[0-9 ]*([\.,][0-9]+)?" value="1234.5">
+  <label class="mdl-textfield__label">Number...</label>
+  <span class="mdl-textfield__error">Input is not a number!</span>
+</div>
+```
+
+&nbsp;2. Add the `mdlext-js-formatfield` class to define the element as a formatfield component.
+```html
+<div class="mdl-textfield mdl-js-textfield mdlext-js-formatfield">
+  <input class="mdl-textfield__input" type="text" 
+    pattern="-?[0-9 ]*([\.,][0-9]+)?" value="1234.5">
+  <label class="mdl-textfield__label">Number...</label>
+  <span class="mdl-textfield__error">Input is not a number!</span>
+</div>
+```
+
+&nbsp;3. Optionally add a `data-formatfield-options` attribute with the given 
+[locale](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl#Locale_identification_and_negotiation). 
+If this step is omitted, the formatfield component uses the browser language as it's locale.
+```html
+<div class="mdl-textfield mdl-js-textfield mdlext-js-formatfield"
+  data-formatfield-options="{'locales': 'nb-NO'}">
+  <input class="mdl-textfield__input" type="text" 
+    pattern="-?[0-9 ]*([\.,][0-9]+)?" value="1234.5">
+  <label class="mdl-textfield__label">Number...</label>
+  <span class="mdl-textfield__error">Input is not a number!</span>
+</div>
+```
+
+### Examples
+* The [snippets/formatfield.html](./snippets/formatfield.html) and the 
+[tests](../../test/formatfield/formatfield.spec.js) provides more detailed examples.
+* Try out the [live demo](http://leifoolsen.github.io/mdl-ext/demo/formatfield.html)
+
+## Public methods
+
+### getOptions()
+Get component configuration options object.
+```
+var options = inputElement.MaterialExtFormatfield.getOptions();
+console.log('locales', options.locales);
+```
+
+### getUnformattedValue()
+An unformatted value is a string value where the locale specific decimal separator
+is replaced with a '.' separator and group separators are stripped.
+The returned value is suitable for parsing to a JavaScript numerical value.
+
+Example
+```javascript
+input.value = '1 234,5';
+inputElement.MaterialExtFormatfield.getUnformattedValue();
+// Returns '1234.5'
+```
+
+## Configuration options
+The MDLEXT CSS classes apply various predefined visual and behavioral enhancements 
+to the formatfield. 
+
+### Available classes and their effects.
+
+| MDLEXT class | Effect | Remarks |
+|--------------|--------|---------|
+|`mdlext-js-formatfield`| Assigns basic MDL behavior to formatfield. | Required. |
+
+
+### Options
+The component can be configured using the `data-formatfield-options` attribute. 
+The attribute value is a JSON string with properties defined by the 
+[Intl.NumberFormat object](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/NumberFormat).
+
+The `data-formatfield-options` attribute must be a valid JSON string. 
+You can use single or double quotes for the JSON properties.
+
+Example 1, single quotes in JSON options string:
+```html
+<input class=" mdlext-js-formatfield" type="text"
+  data-formatfield-options="{'locales': 'nb-NO', 'minimumFractionDigits': 0, 'maximumFractionDigits': 0}">
+```
+
+Example 2, double quotes in JSON options string:
+```html
+<input class=" mdlext-js-formatfield" type="text"
+  data-formatfield-options='{"locales": "nb-NO", "minimumFractionDigits": 0, "maximumFractionDigits": 0}'>
+```
+
+## How to use the component programmatically
+The [tests](../../test/formatfield/formatfield.spec.js) and the 
+[snippets/formatfield.html](./snippets/formatfield.html) 
+provides examples on how to use the component programmatically.
diff --git a/node_modules/mdl-ext/src/formatfield/snippets/formatfield.html b/node_modules/mdl-ext/src/formatfield/snippets/formatfield.html
new file mode 100644
index 0000000..177a367
--- /dev/null
+++ b/node_modules/mdl-ext/src/formatfield/snippets/formatfield.html
@@ -0,0 +1,114 @@
+<p>The formatfield component formats an input field using
+  language sensitive number formatting. It acts as a "pluggable"
+  component. It can be added to a <code>mdl-textfield</code> component or to
+  a <code>&lt;input&gt</code> element.
+</p>
+
+<style>
+  .mdl-data-table .mdl-textfield {
+    width: auto;
+  }
+</style>
+<table class="mdl-data-table mdl-js-data-table mdl-shadow--2dp" style="margin-top: 16px;">
+<thead>
+<tr>
+  <th class="mdl-data-table__cell--non-numeric">Language</th>
+  <th class="mdl-data-table__cell--non-numeric">Input</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+  <td class="mdl-data-table__cell--non-numeric" id="browser-lang">Browser language</td>
+  <td class="mdl-data-table__cell--non-numeric">
+    <div class="mdl-textfield mdl-js-textfield mdlext-js-formatfield" id="sample2-component">
+      <input class="mdl-textfield__input" type="text" pattern="-?[0-9, ]*([\.,][0-9]+)?"
+             id="sample2-input" value="1234.5">
+      <label class="mdl-textfield__label" for="sample2-input">Number...</label>
+      <span class="mdl-textfield__error">Input is not a number!</span>
+    </div>
+    <div id="sample2-unformatted"></div>
+  </td>
+</tr>
+<tr>
+  <td class="mdl-data-table__cell--non-numeric">nb-NO</td>
+  <td class="mdl-data-table__cell--non-numeric">
+    <div class="mdl-textfield mdl-js-textfield mdlext-js-formatfield"
+      data-formatfield-options="{'locales': 'nb-NO'}">
+
+      <input class="mdl-textfield__input" type="text" pattern="-?[0-9 ]*([\.,][0-9]+)?" value="1234.5">
+      <label class="mdl-textfield__label">Number...</label>
+      <span class="mdl-textfield__error">Input is not a number!</span>
+    </div>
+  </td>
+</tr>
+<tr>
+  <td class="mdl-data-table__cell--non-numeric">en-GB</td>
+  <td class="mdl-data-table__cell--non-numeric">
+    <div class="mdl-textfield mdl-js-textfield mdlext-js-formatfield" data-formatfield-options="{'locales': 'en-GB'}">
+      <input class="mdl-textfield__input" type="text" pattern="-?[0-9]*(\.[0-9]+)?" value="1234.5">
+      <label class="mdl-textfield__label">Number...</label>
+      <span class="mdl-textfield__error">Input is not a number!</span>
+    </div>
+  </td>
+</tr>
+<tr>
+  <td class="mdl-data-table__cell--non-numeric">nb-NO, integer</td>
+  <td class="mdl-data-table__cell--non-numeric">
+    <div class="mdl-textfield mdl-js-textfield mdlext-js-formatfield">
+      <input class="mdl-textfield__input" type="text" pattern="-?[0-9]*(\.[0-9]+)?"
+        data-formatfield-options="{'locales': 'nb-NO', 'minimumFractionDigits': 0,'maximumFractionDigits': 0}" value="1234.5">
+
+      <label class="mdl-textfield__label">Number...</label>
+      <span class="mdl-textfield__error">Input is not a number!</span>
+    </div>
+  </td>
+</tr>
+<tr>
+  <td class="mdl-data-table__cell--non-numeric">Percent. Input not supported</td>
+  <td class="mdl-data-table__cell--non-numeric">
+    <div class="mdl-textfield mdl-js-textfield mdlext-js-formatfield">
+      <input class="mdl-textfield__input" type="text" readonly
+        data-formatfield-options="{'locales': 'en-GB', 'style': 'percent'}" value="0.20">
+      <label class="mdl-textfield__label">Number...</label>
+    </div>
+  </td>
+</tr>
+<tr>
+  <td class="mdl-data-table__cell--non-numeric">Currency. Input not supported</td>
+  <td class="mdl-data-table__cell--non-numeric">
+    <div class="mdl-textfield mdl-js-textfield mdlext-js-formatfield">
+      <input class="mdl-textfield__input" type="text" readonly
+        data-formatfield-options="{'locales': 'nb-NO', 'style': 'currency', 'currency': 'NOK'}" value="1234.5">
+      <label class="mdl-textfield__label">Number...</label>
+    </div>
+  </td>
+</tr>
+<tr>
+  <td class="mdl-data-table__cell--non-numeric">Input</td>
+  <td class="mdl-data-table__cell--non-numeric">
+    <input class=" mdlext-js-formatfield" type="text"
+      data-formatfield-options="{'locales': 'nb-NO'}" value="1234.5">
+  </td>
+</tr>
+</tbody>
+</table>
+
+<script>
+  (function() {
+    'use strict';
+    window.addEventListener('load', function() {
+      var lang = navigator.languages
+        ? navigator.languages[0]
+        : navigator.language || navigator.userLanguage;
+
+      document.querySelector('#browser-lang').innerText = 'Browser language (' + lang + ')';
+
+      var formatfieldComponent = document.querySelector('#sample2-component');
+      formatfieldComponent.querySelector('input').addEventListener('blur', function () {
+        var unformatted = document.querySelector('#sample2-unformatted');
+        unformatted.innerText = 'Unformatted: ' + formatfieldComponent.MaterialExtFormatfield.getUnformattedValue();
+      });
+    });
+  }());
+</script>
+
diff --git a/node_modules/mdl-ext/src/grid/_grid-eqjs.scss b/node_modules/mdl-ext/src/grid/_grid-eqjs.scss
new file mode 100644
index 0000000..8068b79
--- /dev/null
+++ b/node_modules/mdl-ext/src/grid/_grid-eqjs.scss
@@ -0,0 +1,321 @@
+@charset "UTF-8";
+
+/**
+ * This code is modified from Material Design Lite _grid.sass,
+ * which is Licensed under the Apache License, Version 2.0
+ * Copyright 2015 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+//////////////////////////////////////////////////////////////////////////////////
+//
+// Element queries for _grid.scss, based on: https://github.com/Snugug/eq.js
+//
+//////////////////////////////////////////////////////////////////////////////////
+
+// Use of this module requires the user to include variables from material-design-lite in hers/his main SASS module
+//@import "../../node_modules/material-design-lite/src/variables";
+.mdlext-grid {
+  display: flex;
+  flex-flow: row wrap;
+  margin: 0 auto;
+  align-items: stretch;
+
+  &.mdlext-grid--no-spacing {
+    padding: 0;
+  }
+
+  & > .mdlext-cell {
+    box-sizing: border-box;
+  }
+
+  & > .mdlext-cell--top {
+    align-self: flex-start;
+  }
+
+  & > .mdlext-cell--middle {
+    align-self: center;
+  }
+
+  & > .mdlext-cell--bottom {
+    align-self: flex-end;
+  }
+
+  & > .mdlext-cell--stretch {
+    align-self: stretch;
+  }
+
+  .mdlext-grid--no-spacing > .mdlext-cell {
+    margin: 0;
+  }
+
+  // Define order override classes.
+  @for $i from 1 through $grid-max-columns {
+    & > .mdlext-cell--order-#{$i} {
+      order: $i;
+    }
+  }
+}
+
+// Mixins for width calculation.
+@mixin _partial-size($size, $columns, $gutter) {
+  width: calc(#{(($size / $columns) * 100) + "%"} - #{$gutter});
+}
+@mixin _full-size($gutter) {
+  @include _partial-size(1, 1, $gutter);
+}
+@mixin _offset-size($size, $columns, $gutter) {
+  margin-left: calc(#{(($size / $columns) * 100) + "%"} + #{$gutter / 2});
+}
+
+@mixin _partial-size-no-spacing($size, $columns) {
+  width: #{(($size / $columns) * 100) + "%"};
+}
+@mixin _full-size-no-spacing() {
+  @include _partial-size-no-spacing(1, 1);
+}
+@mixin _offset-size-no-spacing($size, $columns) {
+  margin-left: #{(($size / $columns) * 100) + "%"};
+}
+
+
+.mdlext-grid {
+
+  @include eq-pts((
+    grid_phone: 0,
+    grid_tablet: strip-unit($grid-tablet-breakpoint),
+    grid_desktop: strip-unit($grid-desktop-breakpoint)
+  ));
+
+  ////////// Phone //////////
+  @include eq('grid_phone') {
+    padding: $grid-phone-margin - ($grid-phone-gutter / 2);
+
+    & > .mdlext-cell {
+      margin: $grid-phone-gutter / 2;
+      @include _partial-size($grid-cell-default-columns, $grid-phone-columns, $grid-phone-gutter);
+    }
+
+    & > .mdlext-cell--hide-phone {
+      display: none !important;
+    }
+
+    // Define order override classes.
+    @for $i from 1 through $grid-max-columns {
+      & > .mdlext-cell--order-#{$i}-phone.mdlext-cell--order-#{$i}-phone {
+        order: $i;
+      }
+    }
+
+    // Define partial sizes for columnNumber < totalColumns.
+    @for $i from 1 through ($grid-phone-columns - 1) {
+      & > .mdlext-cell--#{$i}-col,
+      & > .mdlext-cell--#{$i}-col-phone.mdlext-cell--#{$i}-col-phone {
+        @include _partial-size($i, $grid-phone-columns, $grid-phone-gutter);
+      }
+    }
+
+    // Define 100% for everything else.
+    @for $i from $grid-phone-columns through $grid-desktop-columns {
+      & > .mdlext-cell--#{$i}-col,
+      & > .mdlext-cell--#{$i}-col-phone.mdlext-cell--#{$i}-col-phone {
+        @include _full-size($grid-phone-gutter);
+      }
+    }
+
+    // Define valid phone offsets.
+    @for $i from 1 through ($grid-phone-columns - 1) {
+      & > .mdlext-cell--#{$i}-offset,
+      & > .mdlext-cell--#{$i}-offset-phone.mdlext-cell--#{$i}-offset-phone {
+        @include _offset-size($i, $grid-phone-columns, $grid-phone-gutter);
+      }
+    }
+
+    &.mdlext-grid--no-spacing {
+      padding: 0;
+
+      & > .mdlext-cell {
+        margin: 0;
+        @include _partial-size-no-spacing($grid-cell-default-columns, $grid-phone-columns);
+      }
+
+      // Define partial sizes for columnNumber < totalColumns.
+      @for $i from 1 through ($grid-phone-columns - 1) {
+        & > .mdlext-cell--#{$i}-col,
+        & > .mdlext-cell--#{$i}-col-phone.mdlext-cell--#{$i}-col-phone {
+          @include _partial-size-no-spacing($i, $grid-phone-columns);
+        }
+      }
+
+      // Define 100% for everything else.
+      @for $i from $grid-phone-columns through $grid-desktop-columns {
+        & > .mdlext-cell--#{$i}-col,
+        & > .mdlext-cell--#{$i}-col-phone.mdlext-cell--#{$i}-col-phone {
+          @include _full-size-no-spacing();
+        }
+      }
+
+      // Define valid phone offsets.
+      @for $i from 1 through ($grid-phone-columns - 1) {
+        & > .mdlext-cell--#{$i}-offset,
+        & > .mdlext-cell--#{$i}-offset-phone.mdlext-cell--#{$i}-offset-phone {
+          @include _offset-size-no-spacing($i, $grid-phone-columns);
+        }
+      }
+    }
+  }
+
+  ////////// Tablet //////////
+  @include eq('grid_tablet') {
+    padding: $grid-tablet-margin - ($grid-tablet-gutter / 2);
+
+    & > .mdlext-cell {
+      margin: $grid-tablet-gutter / 2;
+      @include _partial-size($grid-cell-default-columns, $grid-tablet-columns, $grid-tablet-gutter);
+    }
+
+    & > .mdlext-cell--hide-tablet {
+      display: none !important;
+    }
+
+    // Define order override classes.
+    @for $i from 1 through $grid-max-columns {
+      & > .mdlext-cell--order-#{$i}-tablet.mdlext-cell--order-#{$i}-tablet {
+        order: $i;
+      }
+    }
+
+    // Define partial sizes for columnNumber < totalColumns.
+    @for $i from 1 through ($grid-tablet-columns - 1) {
+      & > .mdlext-cell--#{$i}-col,
+      & > .mdlext-cell--#{$i}-col-tablet.mdlext-cell--#{$i}-col-tablet {
+        @include _partial-size($i, $grid-tablet-columns, $grid-tablet-gutter);
+      }
+    }
+
+    // Define 100% for everything else.
+    @for $i from $grid-tablet-columns through $grid-desktop-columns {
+      & > .mdlext-cell--#{$i}-col,
+      & > .mdlext-cell--#{$i}-col-tablet.mdlext-cell--#{$i}-col-tablet {
+        @include _full-size($grid-tablet-gutter);
+      }
+    }
+
+    // Define valid tablet offsets.
+    @for $i from 1 through ($grid-tablet-columns - 1) {
+      & > .mdlext-cell--#{$i}-offset,
+      & > .mdlext-cell--#{$i}-offset-tablet.mdlext-cell--#{$i}-offset-tablet {
+        @include _offset-size($i, $grid-tablet-columns, $grid-tablet-gutter);
+      }
+    }
+
+    &.mdlext-grid--no-spacing {
+      padding: 0;
+
+      & > .mdlext-cell {
+        margin: 0;
+        @include _partial-size-no-spacing($grid-cell-default-columns, $grid-tablet-columns);
+      }
+
+      // Define partial sizes for columnNumber < totalColumns.
+      @for $i from 1 through ($grid-tablet-columns - 1) {
+        & > .mdlext-cell--#{$i}-col,
+        & > .mdlext-cell--#{$i}-col-tablet.mdlext-cell--#{$i}-col-tablet {
+          @include _partial-size-no-spacing($i, $grid-tablet-columns);
+        }
+      }
+
+      // Define 100% for everything else.
+      @for $i from $grid-tablet-columns through $grid-desktop-columns {
+        & > .mdlext-cell--#{$i}-col,
+        & > .mdlext-cell--#{$i}-col-tablet.mdlext-cell--#{$i}-col-tablet {
+          @include _full-size-no-spacing();
+        }
+      }
+
+      // Define valid tablet offsets.
+      @for $i from 1 through ($grid-tablet-columns - 1) {
+        & > .mdlext-cell--#{$i}-offset,
+        & > .mdlext-cell--#{$i}-offset-tablet.mdlext-cell--#{$i}-offset-tablet {
+          @include _offset-size-no-spacing($i, $grid-tablet-columns);
+        }
+      }
+    }
+  }
+
+  ////////// Desktop //////////
+  @include eq('grid_desktop') {
+    padding: $grid-desktop-margin - ($grid-desktop-gutter / 2);
+
+    & > .mdlext-cell {
+      margin: $grid-desktop-gutter / 2;
+      @include _partial-size($grid-cell-default-columns, $grid-desktop-columns, $grid-desktop-gutter);
+    }
+
+    & > .mdlext-cell--hide-desktop {
+      display: none !important;
+    }
+
+    // Define order override classes.
+    @for $i from 1 through $grid-max-columns {
+      & > .mdlext-cell--order-#{$i}-desktop.mdlext-cell--order-#{$i}-desktop {
+        order: $i;
+      }
+    }
+
+    // Define partial sizes for all numbers of columns.
+    @for $i from 1 through $grid-desktop-columns {
+      & > .mdlext-cell--#{$i}-col,
+      & > .mdlext-cell--#{$i}-col-desktop.mdlext-cell--#{$i}-col-desktop {
+        @include _partial-size($i, $grid-desktop-columns, $grid-desktop-gutter);
+      }
+    }
+
+    // Define valid desktop offsets.
+    @for $i from 1 through ($grid-desktop-columns - 1) {
+      & > .mdlext-cell--#{$i}-offset,
+      & > .mdlext-cell--#{$i}-offset-desktop.mdlext-cell--#{$i}-offset-desktop {
+        @include _offset-size($i, $grid-desktop-columns, $grid-desktop-gutter);
+      }
+    }
+
+    &.mdlext-grid--no-spacing {
+      padding: 0;
+
+      & > .mdlext-cell {
+        margin: 0;
+        @include _partial-size-no-spacing($grid-cell-default-columns, $grid-desktop-columns);
+      }
+
+      // Define partial sizes for all numbers of columns.
+      @for $i from 1 through $grid-desktop-columns {
+        & > .mdlext-cell--#{$i}-col,
+        & > .mdlext-cell--#{$i}-col-desktop.mdlext-cell--#{$i}-col-desktop {
+          @include _partial-size-no-spacing($i, $grid-desktop-columns);
+        }
+      }
+
+      // Define valid desktop offsets.
+      @for $i from 1 through ($grid-desktop-columns - 1) {
+        & > .mdlext-cell--#{$i}-offset,
+        & > .mdlext-cell--#{$i}-offset-desktop.mdlext-cell--#{$i}-offset-desktop {
+          @include _offset-size-no-spacing($i, $grid-desktop-columns);
+        }
+      }
+    }
+  }
+}
+
+@include eq-selectors;
diff --git a/node_modules/mdl-ext/src/grid/_grid-media-queries.scss b/node_modules/mdl-ext/src/grid/_grid-media-queries.scss
new file mode 100644
index 0000000..c942ff1
--- /dev/null
+++ b/node_modules/mdl-ext/src/grid/_grid-media-queries.scss
@@ -0,0 +1,238 @@
+@charset "UTF-8";
+
+/**
+ * This code is modified from Material Design Lite _grid.sass,
+ * which is Licensed under the Apache License, Version 2.0
+ * Copyright 2015 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+///////////////////////////////////////////////////////////////////////
+//
+// Grid media queries, modified from Material Design Lite _grid.sass
+//
+///////////////////////////////////////////////////////////////////////
+// Use of this module requires the user to include variables from material-design-lite in hers/his main SASS module
+//@import "../../node_modules/material-design-lite/src/variables";
+
+
+.mdlext-grid {
+  display: flex;
+  flex-flow: row wrap;
+  margin: 0 auto;
+  align-items: stretch;
+
+  &.mdlext-grid--no-spacing {
+    padding: 0;
+  }
+}
+
+.mdlext-cell {
+  box-sizing: border-box;
+}
+
+
+.mdlext-cell--top {
+  align-self: flex-start;
+}
+
+.mdlext-cell--middle {
+  align-self: center;
+}
+
+.mdlext-cell--bottom {
+  align-self: flex-end;
+}
+
+.mdlext-cell--stretch {
+  align-self: stretch;
+}
+
+.mdlext-grid.mdlext-grid--no-spacing > .mdlext-cell {
+  margin: 0;
+}
+
+// Define order override classes.
+@for $i from 1 through $grid-max-columns {
+  .mdlext-cell--order-#{$i} {
+    order: $i;
+  }
+}
+
+
+// Mixins for width calculation.
+@mixin partial-size($size, $columns, $gutter) {
+  width: calc(#{(($size / $columns) * 100) + "%"} - #{$gutter});
+
+  .mdlext-grid--no-spacing > & {
+    width: #{(($size / $columns) * 100) + "%"};
+  }
+}
+
+@mixin full-size($gutter) {
+  @include partial-size(1, 1, $gutter);
+}
+
+@mixin offset-size($size, $columns, $gutter) {
+  margin-left: calc(#{(($size / $columns) * 100) + "%"} + #{$gutter / 2});
+
+  .mdlext-grid.mdlext-grid--no-spacing > & {
+    margin-left: #{(($size / $columns) * 100) + "%"};
+  }
+}
+
+
+
+////////// Phone //////////
+
+/* stylelint-disable */
+@media (max-width: $grid-tablet-breakpoint - 1) {
+/* stylelint-enable */
+  .mdlext-grid {
+    padding: $grid-phone-margin - ($grid-phone-gutter / 2);
+  }
+
+  .mdlext-cell {
+    margin: $grid-phone-gutter / 2;
+    @include partial-size($grid-cell-default-columns, $grid-phone-columns, $grid-phone-gutter);
+  }
+
+  .mdlext-cell--hide-phone {
+    display: none !important;
+  }
+
+  // Define order override classes.
+  @for $i from 1 through $grid-max-columns {
+    .mdlext-cell--order-#{$i}-phone.mdlext-cell--order-#{$i}-phone {
+      order: $i;
+    }
+  }
+
+  // Define partial sizes for columnNumber < totalColumns.
+  @for $i from 1 through ($grid-phone-columns - 1) {
+    .mdlext-cell--#{$i}-col,
+    .mdlext-cell--#{$i}-col-phone.mdlext-cell--#{$i}-col-phone {
+      @include partial-size($i, $grid-phone-columns, $grid-phone-gutter);
+    }
+  }
+
+  // Define 100% for everything else.
+  @for $i from $grid-phone-columns through $grid-desktop-columns {
+    .mdlext-cell--#{$i}-col,
+    .mdlext-cell--#{$i}-col-phone.mdlext-cell--#{$i}-col-phone {
+      @include full-size($grid-phone-gutter);
+    }
+  }
+
+  // Define valid phone offsets.
+  @for $i from 1 through ($grid-phone-columns - 1) {
+    .mdlext-cell--#{$i}-offset,
+    .mdlext-cell--#{$i}-offset-phone.mdlext-cell--#{$i}-offset-phone {
+      @include offset-size($i, $grid-phone-columns, $grid-phone-gutter);
+    }
+  }
+}
+
+
+////////// Tablet //////////
+
+/* stylelint-disable */
+@media (min-width: $grid-tablet-breakpoint) and (max-width: $grid-desktop-breakpoint - 1) { /* stylelint-enable */
+  .mdlext-grid {
+    padding: $grid-tablet-margin - ($grid-tablet-gutter / 2);
+  }
+
+  .mdlext-cell {
+    margin: $grid-tablet-gutter / 2;
+    @include partial-size($grid-cell-default-columns, $grid-tablet-columns, $grid-tablet-gutter);
+  }
+
+  .mdlext-cell--hide-tablet {
+    display: none !important;
+  }
+
+  // Define order override classes.
+  @for $i from 1 through $grid-max-columns {
+    .mdlext-cell--order-#{$i}-tablet.mdlext-cell--order-#{$i}-tablet {
+      order: $i;
+    }
+  }
+
+  // Define partial sizes for columnNumber < totalColumns.
+  @for $i from 1 through ($grid-tablet-columns - 1) {
+    .mdlext-cell--#{$i}-col,
+    .mdlext-cell--#{$i}-col-tablet.mdlext-cell--#{$i}-col-tablet {
+      @include partial-size($i, $grid-tablet-columns, $grid-tablet-gutter);
+    }
+  }
+
+  // Define 100% for everything else.
+  @for $i from $grid-tablet-columns through $grid-desktop-columns {
+    .mdlext-cell--#{$i}-col,
+    .mdlext-cell--#{$i}-col-tablet.mdlext-cell--#{$i}-col-tablet {
+      @include full-size($grid-tablet-gutter);
+    }
+  }
+
+  // Define valid tablet offsets.
+  @for $i from 1 through ($grid-tablet-columns - 1) {
+    .mdlext-cell--#{$i}-offset,
+    .mdlext-cell--#{$i}-offset-tablet.mdlext-cell--#{$i}-offset-tablet {
+      @include offset-size($i, $grid-tablet-columns, $grid-tablet-gutter);
+    }
+  }
+}
+
+
+////////// Desktop //////////
+
+@media (min-width: $grid-desktop-breakpoint) {
+  .mdlext-grid {
+    padding: $grid-desktop-margin - ($grid-desktop-gutter / 2);
+  }
+
+  .mdlext-cell {
+    margin: $grid-desktop-gutter / 2;
+    @include partial-size($grid-cell-default-columns, $grid-desktop-columns, $grid-desktop-gutter);
+  }
+
+  .mdlext-cell--hide-desktop {
+    display: none !important;
+  }
+
+  // Define order override classes.
+  @for $i from 1 through $grid-max-columns {
+    .mdlext-cell--order-#{$i}-desktop.mdlext-cell--order-#{$i}-desktop {
+      order: $i;
+    }
+  }
+
+  // Define partial sizes for all numbers of columns.
+  @for $i from 1 through $grid-desktop-columns {
+    .mdlext-cell--#{$i}-col,
+    .mdlext-cell--#{$i}-col-desktop.mdlext-cell--#{$i}-col-desktop {
+      @include partial-size($i, $grid-desktop-columns, $grid-desktop-gutter);
+    }
+  }
+
+  // Define valid desktop offsets.
+  @for $i from 1 through ($grid-desktop-columns - 1) {
+    .mdlext-cell--#{$i}-offset,
+    .mdlext-cell--#{$i}-offset-desktop.mdlext-cell--#{$i}-offset-desktop {
+      @include offset-size($i, $grid-desktop-columns, $grid-desktop-gutter);
+    }
+  }
+}
+
diff --git a/node_modules/mdl-ext/src/grid/readme.md b/node_modules/mdl-ext/src/grid/readme.md
new file mode 100644
index 0000000..569e7c8
--- /dev/null
+++ b/node_modules/mdl-ext/src/grid/readme.md
@@ -0,0 +1,52 @@
+# Grid
+
+![Grid](../../etc/grid.png)
+
+A responsive **grid** based on **element queries** in favour of media queries.
+
+## Introduction
+Grids provide users with a way to view content in an organized manner that might otherwise be difficult to 
+understand or retain. Their design and use is an important factor in the overall user experience.
+
+The Material Design Lite Ext (MDLEXT) grid has two versions; one version based on media queries and one version 
+based on **element queries**. The MDLEXT grid is a copy of the 
+[Material Design Lite grid](https://github.com/google/material-design-lite/tree/master/src/grid) - with additional 
+element queries support to distribute grid cells in a more responsive fashion.
+
+### How to use the eq.js version of MDLEXT grid
+
+&nbsp;1. Install [eq.js](https://github.com/Snugug/eq.js).
+```sh
+$ npm install --save eq.js
+```
+
+&nbsp;2. Import `mdl-ext-eqjs.scss` in your main SASS file. Remove `mdl-ext.scss` - they can not co exist.
+```css
+@import '../node_modules/mdl-ext/src/mdl-ext-eqjs';
+```
+
+&nbsp;3. Import or Require `eq.js`.  
+```javascript
+const eqjs = require('eq.js'); // ... or:  import eqjs from 'eq.js';
+```
+
+&nbsp;4. Optionally trigger `eq.js`<br/>
+If you're loading html fragments using e.g. Ajax, then trigger `eq.js` after page load.
+
+```javascript
+window.fetch(href, {method: 'get'})
+ .then(response => response.text())
+ .then(text => {
+   contentPanelEl.insertAdjacentHTML('afterbegin', text);
+
+   // Trigger eq.js
+   eqjs.refreshNodes();
+   eqjs.query(undefined, true);
+})
+.catch(err => console.error(err));
+```
+
+An example of how to use `eq.js` in a SPA can be found [here](https://github.com/leifoolsen/mdl-webpack).     
+
+## To include a MDLEXT **grid** component:
+Folow the documention for the [original mdl-grid](https://github.com/google/material-design-lite/blob/master/src/grid/README.md#to-include-an-mdl-grid-component). Just replace `mdl-` with `mdlext-`, and you're good to go. 
diff --git a/node_modules/mdl-ext/src/grid/snippets/grid.html b/node_modules/mdl-ext/src/grid/snippets/grid.html
new file mode 100644
index 0000000..26e6b11
--- /dev/null
+++ b/node_modules/mdl-ext/src/grid/snippets/grid.html
@@ -0,0 +1,121 @@
+<p>Element queries vs Media Queries. Drag the slider to see the effect</p>
+
+<style>
+
+  .demo-grid {
+    margin-bottom: 16px;
+  }
+  .demo-grid .mdl-grid,
+  .demo-grid .mdlext-grid {
+    /*padding: 0;*/
+  }
+  .demo-grid .mdl-cell,
+  .demo-grid .mdlext-cell {
+    background: rgb(63,81,181);
+    text-align: center;
+    color: white;
+    padding: 10px;
+    border: 1px solid #aaaaaa;
+  }
+  .demo-grid .mdl-cell:nth-child(odd),
+  .demo-grid .mdlext-cell:nth-child(odd) {
+    background: rgb(33,150,243);
+  }
+  .demo-grid-c .mdl-cell,
+  .demo-grid-c .mdlext-cell {
+    background: rgb(255,213,79);
+    color: #000;
+    border: 0;
+  }
+  .demo-grid-c .mdl-cell:nth-child(odd),
+  .demo-grid-c .mdlext-cell:nth-child(odd) {
+    background: rgb(165,214,167);
+    color: #000;
+  }
+</style>
+
+
+<p id="grid-container-width" style="text-align: center;">
+  <strong>100</strong>%
+  <input class="mdl-slider mdl-js-slider" type="range" min="50" max="100" value="100" step="10" tabindex="0">
+</p>
+
+<div style="border: 1px solid #dddddd;">
+  <div id="grid-container" style="margin: 0 auto;">
+
+    <h5>mdlext-grid, using element queries</h5>
+    <div class="demo-grid">
+      <div class="mdlext-grid mdlext-grid--no-spacing">
+        <div class="mdlext-cell mdlext-cell--1-col">1</div>
+        <div class="mdlext-cell mdlext-cell--1-col">1</div>
+        <div class="mdlext-cell mdlext-cell--1-col">1</div>
+        <div class="mdlext-cell mdlext-cell--1-col">1</div>
+        <div class="mdlext-cell mdlext-cell--1-col">1</div>
+        <div class="mdlext-cell mdlext-cell--1-col">1</div>
+        <div class="mdlext-cell mdlext-cell--1-col">1</div>
+        <div class="mdlext-cell mdlext-cell--1-col">1</div>
+        <div class="mdlext-cell mdlext-cell--1-col">1</div>
+        <div class="mdlext-cell mdlext-cell--1-col">1</div>
+        <div class="mdlext-cell mdlext-cell--1-col">1</div>
+        <div class="mdlext-cell mdlext-cell--1-col">1</div>
+      </div>
+    </div>
+
+    <div class="demo-grid demo-grid-c">
+      <div class="mdlext-grid mdlext-grid--no-spacing">
+        <div class="mdlext-cell mdlext-cell--4-col mdlext-cell--2-col-tablet mdlext-cell--1-col-phone">4 (2 tablet, 1 phone)</div>
+        <div class="mdlext-cell mdlext-cell--6-col mdlext-cell--4-col-tablet mdlext-cell--3-col-phone">6 (4 tablet, 3 phone)</div>
+        <div class="mdlext-cell mdlext-cell--2-col mdlext-cell--2-col-tablet mdlext-cell--hide-phone">2 (2 tablet, hide phone)</div>
+      </div>
+    </div>
+
+
+    <h5>mdl-grid, using media queries</h5>
+    <div class="demo-grid">
+      <div class="mdl-grid mdl-grid--no-spacing">
+        <div class="mdl-cell mdl-cell--1-col">1</div>
+        <div class="mdl-cell mdl-cell--1-col">1</div>
+        <div class="mdl-cell mdl-cell--1-col">1</div>
+        <div class="mdl-cell mdl-cell--1-col">1</div>
+        <div class="mdl-cell mdl-cell--1-col">1</div>
+        <div class="mdl-cell mdl-cell--1-col">1</div>
+        <div class="mdl-cell mdl-cell--1-col">1</div>
+        <div class="mdl-cell mdl-cell--1-col">1</div>
+        <div class="mdl-cell mdl-cell--1-col">1</div>
+        <div class="mdl-cell mdl-cell--1-col">1</div>
+        <div class="mdl-cell mdl-cell--1-col">1</div>
+        <div class="mdl-cell mdl-cell--1-col">1</div>
+      </div>
+    </div>
+
+    <div class="demo-grid demo-grid-c">
+      <div class="mdl-grid mdl-grid--no-spacing">
+        <div class="mdl-cell mdl-cell--4-col mdl-cell--2-col-tablet mdl-cell--1-col-phone">4 (2 tablet, 1 phone)</div>
+        <div class="mdl-cell mdl-cell--6-col mdl-cell--4-col-tablet mdl-cell--3-col-phone">6 (4 tablet, 3 phone)</div>
+        <div class="mdl-cell mdl-cell--2-col mdl-cell--2-col-tablet mdl-cell--hide-phone">2 (2 tablet, hide phone)</div>
+      </div>
+    </div>
+  </div>
+</div>
+
+<script>
+  'use strict';
+  window.addEventListener('load', function() {
+    (function() {
+      'use strict';
+      var widthLabel = document.querySelector('#grid-container-width strong');
+      var slider = document.querySelector('#grid-container-width input');
+
+      slider.addEventListener('input', function(e) {
+        setWidth(this.value);
+      }.bind(slider));
+
+      function setWidth(value) {
+        widthLabel.innerText = value;
+        document.querySelector('#grid-container').style.width = value + '%';
+        eqjs.refreshNodes();
+        eqjs.query(undefined, true);
+      }
+    }());
+  });
+</script>
diff --git a/node_modules/mdl-ext/src/index.js b/node_modules/mdl-ext/src/index.js
new file mode 100644
index 0000000..b6fa845
--- /dev/null
+++ b/node_modules/mdl-ext/src/index.js
@@ -0,0 +1,10 @@
+import './utils';
+import './accordion/accordion';
+import './collapsible/collapsible';
+import './carousel/carousel';
+import './lightboard/lightboard';
+import './lightbox/lightbox';
+import './menu-button/menu-button';
+import './selectfield/selectfield';
+import './formatfield/formatfield';
+import './sticky-header/sticky-header';
diff --git a/node_modules/mdl-ext/src/lightboard/_lightboard-eqjs.scss b/node_modules/mdl-ext/src/lightboard/_lightboard-eqjs.scss
new file mode 100644
index 0000000..7d2666b
--- /dev/null
+++ b/node_modules/mdl-ext/src/lightboard/_lightboard-eqjs.scss
@@ -0,0 +1,110 @@
+@charset "UTF-8";
+//////////////////////////////////////////////////////////////////////////////////
+//
+// Element queries for _lightbox.scss, based on: https://github.com/Snugug/eq.js
+//
+//////////////////////////////////////////////////////////////////////////////////
+
+@import "../variables";
+@import "../functions";
+
+.mdlext-lightboard {
+
+  @include eq-pts((
+    lightboard_medium_small: strip-unit($mdlext-lightboard-medium-small-breakpoint),
+    lightboard_medium: strip-unit($mdlext-lightboard-medium-breakpoint),
+    lightboard_medium_large: strip-unit($mdlext-lightboard-medium-large-breakpoint),
+    lightboard_large: strip-unit($mdlext-lightboard-large-breakpoint)
+  ));
+
+  ////// small - meduim-small //////
+  @include eq('lightboard_medium_small') {
+    padding: calc((#{$mdlext-lightboard-medium-small-margin} - #{$mdlext-lightboard-medium-small-gutter}) / 2);
+
+    .mdlext-lightboard__slide {
+      margin: calc(#{$mdlext-lightboard-medium-small-gutter} / 2);
+      width: calc(1 / #{$mdlext-lightboard-medium-small-columns} * 100% - #{$mdlext-lightboard-medium-small-gutter});
+
+      .mdlext-lightboard__slide__frame figure {
+        margin: $mdlext-lightboard-medium-small-frame-width;
+      }
+    }
+    &.mdlext-lightboard--no-spacing {
+      padding: 0;
+
+      .mdlext-lightboard__slide {
+        margin: 0;
+        width: calc(1 / #{$mdlext-lightboard-medium-small-columns} * 100%);
+      }
+    }
+  }
+
+  ////// meduim-small - medium //////
+  @include eq('lightboard_medium') {
+    padding: calc((#{$mdlext-lightboard-medium-margin} - #{$mdlext-lightboard-medium-gutter}) / 2);
+
+    .mdlext-lightboard__slide {
+      margin: calc(#{$mdlext-lightboard-medium-gutter} / 2);
+      width: calc(1 / #{$mdlext-lightboard-medium-columns} * 100% - #{$mdlext-lightboard-medium-gutter});
+
+      .mdlext-lightboard__slide__frame figure {
+        margin: $mdlext-lightboard-medium-frame-width;
+      }
+    }
+    &.mdlext-lightboard--no-spacing {
+      padding: 0;
+
+      .mdlext-lightboard__slide {
+        margin: 0;
+        width: calc(1 / #{$mdlext-lightboard-medium-columns} * 100%);
+      }
+    }
+  }
+
+  ////// meduim - medium-large //////
+  @include eq('lightboard_medium_large') {
+    padding: calc((#{$mdlext-lightboard-medium-large-margin} - #{$mdlext-lightboard-medium-large-gutter}) / 2);
+
+    .mdlext-lightboard__slide {
+      margin: calc(#{$mdlext-lightboard-medium-large-gutter} / 2);
+      width: calc(1 / #{$mdlext-lightboard-medium-large-columns} * 100% - #{$mdlext-lightboard-medium-large-gutter});
+
+      .mdlext-lightboard__slide__frame figure {
+        margin: $mdlext-lightboard-medium-large-frame-width;
+      }
+    }
+    &.mdlext-lightboard--no-spacing {
+      padding: 0;
+
+      .mdlext-lightboard__slide {
+        margin: 0;
+        width: calc(1 / #{$mdlext-lightboard-medium-large-columns} * 100%);
+      }
+    }
+  }
+
+  ////// meduim-large - large //////
+  @include eq('lightboard_large') {
+    padding: calc((#{$mdlext-lightboard-large-margin} - #{$mdlext-lightboard-large-gutter}) / 2);
+
+    .mdlext-lightboard__slide {
+      margin: calc(#{$mdlext-lightboard-large-gutter} / 2);
+      width: calc(1 / #{$mdlext-lightboard-large-columns} * 100% - #{$mdlext-lightboard-large-gutter});
+
+      .mdlext-lightboard__slide__frame figure {
+        margin: $mdlext-lightboard-large-frame-width;
+      }
+    }
+    &.mdlext-lightboard--no-spacing {
+      padding: 0;
+
+      .mdlext-lightboard__slide {
+        margin: 0;
+        width: calc(1 / #{$mdlext-lightboard-large-columns} * 100%);
+      }
+    }
+  }
+}
+
+@include eq-selectors;
+
diff --git a/node_modules/mdl-ext/src/lightboard/_lightboard-media-queries.scss b/node_modules/mdl-ext/src/lightboard/_lightboard-media-queries.scss
new file mode 100644
index 0000000..b87f830
--- /dev/null
+++ b/node_modules/mdl-ext/src/lightboard/_lightboard-media-queries.scss
@@ -0,0 +1,113 @@
+@charset "UTF-8";
+
+//////////////////////////////
+//
+// Lightboard media queries
+//
+//////////////////////////////
+@import "../variables";
+
+////////// Small /////////////
+//@media (max-width: $mdlext-lightboard-medium-small-breakpoint - 1) {
+//  // This is the default, see: _lightboard.scss
+//}
+
+////////// Medium small //////////
+/* stylelint-disable */
+@media (min-width: $mdlext-lightboard-medium-small-breakpoint) and (max-width: $mdlext-lightboard-medium-breakpoint - 1) { /* stylelint-enable */
+  .mdlext-lightboard {
+    padding: calc((#{$mdlext-lightboard-medium-small-margin} - #{$mdlext-lightboard-medium-small-gutter}) / 2);
+
+    .mdlext-lightboard__slide {
+      margin: calc(#{$mdlext-lightboard-medium-small-gutter} / 2);
+      width: calc(1 / #{$mdlext-lightboard-medium-small-columns} * 100% - #{$mdlext-lightboard-medium-small-gutter});
+
+      .mdlext-lightboard__slide__frame figure {
+        margin: $mdlext-lightboard-medium-small-frame-width;
+      }
+    }
+    &.mdlext-lightboard--no-spacing {
+      padding: 0;
+
+      .mdlext-lightboard__slide {
+        margin: 0;
+        width: calc(1 / #{$mdlext-lightboard-medium-small-columns} * 100%);
+      }
+    }
+  }
+}
+
+////////// Medium //////////
+/* stylelint-disable */
+@media (min-width: $mdlext-lightboard-medium-breakpoint) and (max-width: $mdlext-lightboard-medium-large-breakpoint - 1) { /* stylelint-enable */
+  .mdlext-lightboard {
+    padding: calc((#{$mdlext-lightboard-medium-margin} - #{$mdlext-lightboard-medium-gutter}) / 2);
+
+    .mdlext-lightboard__slide {
+      margin: calc(#{$mdlext-lightboard-medium-gutter} / 2);
+      width: calc(1 / #{$mdlext-lightboard-medium-columns} * 100% - #{$mdlext-lightboard-medium-gutter});
+
+      .mdlext-lightboard__slide__frame figure {
+        margin: $mdlext-lightboard-medium-frame-width;
+      }
+    }
+    &.mdlext-lightboard--no-spacing {
+      padding: 0;
+
+      .mdlext-lightboard__slide {
+        margin: 0;
+        width: calc(1 / #{$mdlext-lightboard-medium-columns} * 100%);
+      }
+    }
+  }
+}
+
+////////// Medium large //////////
+/* stylelint-disable */
+@media (min-width: $mdlext-lightboard-medium-large-breakpoint)  and (max-width: $mdlext-lightboard-large-breakpoint - 1) { /* stylelint-enable */
+  .mdlext-lightboard {
+    padding: calc((#{$mdlext-lightboard-medium-large-margin} - #{$mdlext-lightboard-medium-large-gutter}) / 2);
+
+    .mdlext-lightboard__slide {
+      margin: calc(#{$mdlext-lightboard-medium-large-gutter} / 2);
+      width: calc(1 / #{$mdlext-lightboard-medium-large-columns} * 100% - #{$mdlext-lightboard-medium-large-gutter});
+
+      .mdlext-lightboard__slide__frame figure {
+        margin: $mdlext-lightboard-medium-large-frame-width;
+      }
+    }
+    &.mdlext-lightboard--no-spacing {
+      padding: 0;
+
+      .mdlext-lightboard__slide {
+        margin: 0;
+        width: calc(1 / #{$mdlext-lightboard-medium-large-columns} * 100%);
+      }
+    }
+  }
+}
+
+////////// Large //////////
+@media (min-width: $mdlext-lightboard-large-breakpoint) {
+  .mdlext-lightboard {
+    padding: calc((#{$mdlext-lightboard-large-margin} - #{$mdlext-lightboard-large-gutter}) / 2);
+
+    .mdlext-lightboard__slide {
+      margin: calc(#{$mdlext-lightboard-large-gutter} / 2);
+      width: calc(1 / #{$mdlext-lightboard-large-columns} * 100% - #{$mdlext-lightboard-large-gutter});
+
+      .mdlext-lightboard__slide__frame figure {
+        margin: $mdlext-lightboard-large-frame-width;
+      }
+    }
+    &.mdlext-lightboard--no-spacing {
+      padding: 0;
+
+      .mdlext-lightboard__slide {
+        margin: 0;
+        width: calc(1 / #{$mdlext-lightboard-large-columns} * 100%);
+      }
+    }
+  }
+}
+
diff --git a/node_modules/mdl-ext/src/lightboard/_lightboard.scss b/node_modules/mdl-ext/src/lightboard/_lightboard.scss
new file mode 100644
index 0000000..775d283
--- /dev/null
+++ b/node_modules/mdl-ext/src/lightboard/_lightboard.scss
@@ -0,0 +1,178 @@
+@charset "UTF-8";
+
+/**
+ * Copyright 2016 Leif Olsen. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * A lightboard is a translucent surface illuminated from behind, used for situations
+ * where a shape laid upon the surface needs to be seen with high contrast. In the "old days" of photography
+ * photograpers used a lightboard to get a quick view of their slides. The goal is to create a responsive lightbox
+ * design, based on flex layout, similar to what is used in Adobe LightRoom to browse images.
+ */
+
+// Use of this module requires the user to include variables from material-design-lite
+//@import "../../node_modules/material-design-lite/src/variables";
+//@import "../../node_modules/material-design-lite/src/mixins";
+@import "../variables";
+
+ul.mdlext-lightboard {
+  list-style: none;
+}
+
+.mdlext-lightboard {
+  box-sizing: border-box;
+  margin: 0 auto;
+  padding: 0;
+  display: flex;
+  flex-flow:row wrap;
+  align-items: stretch;
+
+  *,
+  *::before,
+  *::after,
+  input[type="search"] {
+    box-sizing: border-box;
+  }
+
+  .mdlext-lightboard__slide {
+    background-color: $mdlext-lightboard-slide-background-color;
+    border: 1px solid $mdlext-lightboard-slide-border-color;
+    border-radius: $mdlext-lightboard-slide-border-radius;
+    box-shadow: $mdlext-lightboard-slide-box-shadow;
+    position: relative;
+    display: block;
+    max-width: $mdlext-lightboard-slide-max-size;
+
+    &::before {
+      // 1:1 ratio
+      // TODO: Use a class for ratio so the grid can display slides with different ratios (16:9, 16:10, 4:3 ...)
+      content: '';
+      display: block;
+      padding-top: 100%;
+    }
+    &:hover,
+    &:active,
+    &:focus {
+      border-color: $mdlext-lightboard-slide-border-color-hover;
+      background-color: $mdlext-lightboard-slide-background-color-hover;
+      box-shadow: $mdlext-lightboard-slide-box-shadow-hover;
+
+      figcaption {
+        color: rgba(0, 0, 0, 1) !important;
+        background-color: rgba(255, 255, 255, 0.2);
+      }
+    }
+    &:focus {
+      outline-offset: -2px;
+      outline-color: $mdlext-lightboard-focus-outline-color;
+    }
+    &[aria-selected='true'] {
+      background-color: $mdlext-lightboard-slide-active-bacground-color;
+
+      figcaption {
+        color: rgba(0, 0, 0, 1) !important;
+        background-color: rgba(255, 255, 255, 0.2);
+      }
+    }
+    &__frame,
+    &__ripple-container {
+      text-decoration: none;
+      display: block;
+      overflow: hidden;
+      position: absolute;
+      top: 0;
+      left: 0;
+      right: 0;
+      bottom: 0;
+
+      &:focus {
+        outline-offset: -2px;
+        outline-color: $mdlext-lightboard-focus-outline-color;
+      }
+      & .mdl-ripple {
+        background: $mdlext-lightboard-ripple-color;
+      }
+      figure {
+        display: block;
+        position: absolute;
+        top: 0;
+        left: 0;
+        right: 0;
+        bottom: 0;
+
+        img {
+          position: absolute;
+          top: 0;
+          left: 0;
+          right: 0;
+          bottom: 0;
+          margin: auto;
+          max-width: 100%;
+          max-height: 100%;
+          border-width: 0;
+          border-radius: $mdlext-lightboard-slide-inner-border-radius;
+        }
+        figcaption {
+          @include typo-caption($colorContrast: false, $usePreferred: true);
+
+          color: $mdlext-lightboard-figcaption-text-color;
+          position: absolute;
+          bottom: -2px;
+          white-space: nowrap;
+          overflow: hidden;
+          max-width: 100%;
+          width: 100%;
+          text-align: center;
+          text-overflow: ellipsis;
+          padding: 4px 0;
+        }
+      }
+      &:hover {
+        figcaption {
+          // As far as I can see there is no way to darken/lighten a text color
+          // defined by MDL, due to the "unqote" functions.
+          // So this is a hack
+          color: rgba(0, 0, 0, 1) !important;
+          background-color: rgba(255, 255, 255, 0.2);
+        }
+      }
+    }
+  }
+}
+
+////// Media / Element queries default, Small //////
+.mdlext-lightboard {
+  padding: calc((#{$mdlext-lightboard-small-margin} - #{$mdlext-lightboard-small-gutter}) / 2);
+
+  .mdlext-lightboard__slide {
+    margin: calc(#{$mdlext-lightboard-small-gutter} / 2);
+    width: calc(1 / #{$mdlext-lightboard-small-columns} * 100% - #{$mdlext-lightboard-small-gutter});
+
+    .mdlext-lightboard__slide__frame figure {
+      margin: $mdlext-lightboard-small-frame-width;
+    }
+  }
+  &.mdlext-lightboard--no-spacing {
+    padding: 0;
+
+    .mdlext-lightboard__slide {
+      margin: 0;
+      width: calc(1 / #{$mdlext-lightboard-small-columns} * 100%);
+    }
+  }
+}
+
+// Import one of _lightboard-media-queries.scss or _lightboard-eq-js.scss to complete SASS
diff --git a/node_modules/mdl-ext/src/lightboard/lightboard.js b/node_modules/mdl-ext/src/lightboard/lightboard.js
new file mode 100644
index 0000000..9a49559
--- /dev/null
+++ b/node_modules/mdl-ext/src/lightboard/lightboard.js
@@ -0,0 +1,332 @@
+/**
+ * @license
+ * Copyright 2016 Leif Olsen. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * This code is built with Google Material Design Lite,
+ * which is Licensed under the Apache License, Version 2.0
+ */
+
+/**
+ * A lightboard is a translucent surface illuminated from behind, used for situations
+ * where a shape laid upon the surface needs to be seen with high contrast. In the "old days" of photography
+ * photograpers used a lightboard to get a quick view of their slides. The goal is to create a responsive lightbox
+ * design, based on flex layout, similar to what is used in Adobe LightRoom to browse images.
+ */
+
+import {
+  VK_ENTER,
+  VK_SPACE,
+  VK_END,
+  VK_HOME,
+  VK_ARROW_LEFT,
+  VK_ARROW_UP,
+  VK_ARROW_RIGHT,
+  VK_ARROW_DOWN,
+  IS_UPGRADED,
+  MDL_RIPPLE,
+  MDL_RIPPLE_COMPONENT,
+  MDL_RIPPLE_EFFECT,
+  MDL_RIPPLE_EFFECT_IGNORE_EVENTS
+} from '../utils/constants';
+
+const MDL_RIPPLE_CONTAINER = 'mdlext-lightboard__slide__ripple-container';
+
+(function() {
+  'use strict';
+
+  //const LIGHTBOARD = 'mdlext-lightboard';
+  const LIGHTBOARD_ROLE = 'grid';
+  const SLIDE = 'mdlext-lightboard__slide';
+  const SLIDE_ROLE  = 'gridcell';
+  const SLIDE_TABSTOP = 'mdlext-lightboard__slide__frame';
+  /**
+   * @constructor
+   * @param {Element} element The element that will be upgraded.
+   */
+  const MaterialExtLightboard = function MaterialExtLightboard(element) {
+    // Stores the element.
+    this.element_ = element;
+
+    // Initialize instance.
+    this.init();
+  };
+  window['MaterialExtLightboard'] = MaterialExtLightboard;
+
+
+  // Helpers
+  const getSlide = element => {
+    return element ? element.closest(`.${SLIDE}`) : null;
+  };
+
+
+
+  // Private methods.
+
+  /**
+   * Select a slide, i.e. set aria-selected="true"
+   * @param element
+   * @private
+   */
+  MaterialExtLightboard.prototype.selectSlide_ = function(element) {
+    const slide = getSlide(element);
+    if( slide && !slide.hasAttribute('aria-selected') ) {
+      [...this.element_.querySelectorAll(`.${SLIDE}[aria-selected="true"]`)]
+        .forEach(selectedSlide => selectedSlide.removeAttribute('aria-selected'));
+
+      slide.setAttribute('aria-selected', 'true');
+    }
+  };
+
+
+  /**
+   * Dispatch select event
+   * @param {Element} slide The slide that caused the event
+   * @private
+   */
+  MaterialExtLightboard.prototype.dispatchSelectEvent_ = function ( slide ) {
+    this.element_.dispatchEvent(
+      new CustomEvent('select', {
+        bubbles: true,
+        cancelable: true,
+        detail: { source: slide }
+      })
+    );
+  };
+
+  /**
+   * Handles custom command event, 'first', 'next', 'prev', 'last', 'select' or upgrade
+   * @param event. A custom event
+   * @private
+   */
+  MaterialExtLightboard.prototype.commandHandler_ = function( event ) {
+    event.preventDefault();
+    event.stopPropagation();
+
+    if(event && event.detail) {
+      this.command(event.detail);
+    }
+  };
+
+
+  // Public methods
+
+  /**
+   * Initialize lightboard slides
+   * @public
+   */
+  MaterialExtLightboard.prototype.upgradeSlides = function() {
+
+    const addRipple = slide => {
+      // Use slide frame as ripple container
+      if(!slide.querySelector(`.${MDL_RIPPLE_CONTAINER}`)) {
+        const a = slide.querySelector(`.${SLIDE_TABSTOP}`);
+        if(a) {
+          const rippleContainer = a;
+          rippleContainer.classList.add(MDL_RIPPLE_CONTAINER);
+          rippleContainer.classList.add(MDL_RIPPLE_EFFECT);
+          const ripple = document.createElement('span');
+          ripple.classList.add(MDL_RIPPLE);
+          rippleContainer.appendChild(ripple);
+          componentHandler.upgradeElement(rippleContainer, MDL_RIPPLE_COMPONENT);
+        }
+      }
+    };
+
+    const hasRippleEffect = this.element_.classList.contains(MDL_RIPPLE_EFFECT);
+
+    [...this.element_.querySelectorAll(`.${SLIDE}`)].forEach( slide => {
+
+      slide.setAttribute('role', SLIDE_ROLE);
+
+      if(!slide.querySelector('a')) {
+        slide.setAttribute('tabindex', '0');
+      }
+      if(hasRippleEffect) {
+        addRipple(slide);
+      }
+    });
+  };
+  MaterialExtLightboard.prototype['upgradeSlides'] = MaterialExtLightboard.prototype.upgradeSlides;
+
+
+  /**
+   * Execute command
+   * @param detail
+   * @public
+   */
+  MaterialExtLightboard.prototype.command = function( detail ) {
+
+    const firstSlide = () => {
+      return this.element_.querySelector(`.${SLIDE}:first-child`);
+    };
+
+    const lastSlide = () => {
+      return this.element_.querySelector(`.${SLIDE}:last-child`);
+    };
+
+    const nextSlide = () => {
+      const slide = this.element_.querySelector(`.${SLIDE}[aria-selected="true"]`).nextElementSibling;
+      return slide ? slide : firstSlide();
+    };
+
+    const prevSlide = () => {
+      const slide = this.element_.querySelector(`.${SLIDE}[aria-selected="true"]`).previousElementSibling;
+      return slide ? slide : lastSlide();
+    };
+
+    if(detail && detail.action) {
+
+      const { action, target } = detail;
+
+      let slide;
+      switch (action.toLowerCase()) {
+        case 'select':
+          slide = getSlide(target);
+          this.dispatchSelectEvent_(slide);
+          break;
+        case 'first':
+          slide = firstSlide();
+          break;
+        case 'next':
+          slide = nextSlide();
+          break;
+        case 'prev':
+          slide = prevSlide();
+          break;
+        case 'last':
+          slide = lastSlide();
+          break;
+        case 'upgrade':
+          this.upgradeSlides();
+          break;
+        default:
+          throw new Error(`Unknown action "${action}". Action must be one of "first", "next", "prev", "last", "select" or "upgrade"`);
+      }
+
+      if (slide) {
+        const a = slide.querySelector('a');
+        if (a) {
+          a.focus();
+        }
+        else {
+          slide.focus();
+        }
+
+        // Workaround for JSDom testing:
+        // In JsDom 'element.focus()' does not trigger any focus event
+        if(!slide.hasAttribute('aria-selected')) {
+          this.selectSlide_(slide);
+        }
+
+      }
+    }
+  };
+  MaterialExtLightboard.prototype['command'] = MaterialExtLightboard.prototype.command;
+
+
+  /**
+   * Initialize component
+   */
+  MaterialExtLightboard.prototype.init = function() {
+
+    const keydownHandler = event => {
+
+      if(event.target !== this.element_) {
+        let action;
+        let target;
+        switch (event.keyCode) {
+          case VK_HOME:
+            action = 'first';
+            break;
+          case VK_END:
+            action = 'last';
+            break;
+          case VK_ARROW_UP:
+          case VK_ARROW_LEFT:
+            action = 'prev';
+            break;
+          case VK_ARROW_DOWN:
+          case VK_ARROW_RIGHT:
+            action = 'next';
+            break;
+          case VK_ENTER:
+          case VK_SPACE:
+            action = 'select';
+            target = event.target;
+            break;
+        }
+        if(action)  {
+          event.preventDefault();
+          event.stopPropagation();
+          this.command( { action: action, target: target } );
+        }
+      }
+    };
+
+    const clickHandler = event => {
+      event.preventDefault();
+      event.stopPropagation();
+
+      if(event.target !== this.element_) {
+        this.command( { action: 'select', target: event.target } );
+      }
+    };
+
+    const focusHandler = event => {
+      event.preventDefault();
+      event.stopPropagation();
+
+      if(event.target !== this.element_) {
+        this.selectSlide_(event.target);
+      }
+    };
+
+
+    if (this.element_) {
+      this.element_.setAttribute('role', LIGHTBOARD_ROLE);
+
+      if (this.element_.classList.contains(MDL_RIPPLE_EFFECT)) {
+        this.element_.classList.add(MDL_RIPPLE_EFFECT_IGNORE_EVENTS);
+      }
+
+      // Remove listeners, just in case ...
+      this.element_.removeEventListener('command', this.commandHandler_);
+      this.element_.removeEventListener('keydown', keydownHandler);
+      this.element_.removeEventListener('click', clickHandler);
+      this.element_.removeEventListener('focus', focusHandler);
+
+      this.element_.addEventListener('command', this.commandHandler_.bind(this), false);
+      this.element_.addEventListener('keydown', keydownHandler, true);
+      this.element_.addEventListener('click', clickHandler, true);
+      this.element_.addEventListener('focus', focusHandler, true);
+
+      this.upgradeSlides();
+
+      this.element_.classList.add(IS_UPGRADED);
+    }
+  };
+
+  // The component registers itself. It can assume componentHandler is available
+  // in the global scope.
+  /* eslint no-undef: 0 */
+  /* jshint undef:false */
+  componentHandler.register({
+    constructor: MaterialExtLightboard,
+    classAsString: 'MaterialExtLightboard',
+    cssClass: 'mdlext-js-lightboard',
+    widget: true
+  });
+
+})();
diff --git a/node_modules/mdl-ext/src/lightboard/readme.md b/node_modules/mdl-ext/src/lightboard/readme.md
new file mode 100644
index 0000000..429e88e
--- /dev/null
+++ b/node_modules/mdl-ext/src/lightboard/readme.md
@@ -0,0 +1,447 @@
+# Lightboard
+
+![Lightboard](../../etc/lightboard.png)
+
+Thumbnails in a responsive, fluent grid.
+
+## Introduction
+A lightboard is a translucent surface illuminated from behind, used for situations where a shape laid 
+upon the surface needs to be seen with high contrast. In the "old days" of photography photograpers 
+used a lightboard to get a quick view of, sorting and organizing their slides.
+
+The Material Design Lite Ext (MDLEXT) lightboard is defined and enclosed by a container element. The slides are 
+distributed in a row column fashion, with repect to the available screen size. The slides scales proportionally to fill 
+available horizontal space, or the available content size, depending on the type of queries you choose to apply 
+for your responsive breakpoints. The number of slides per row depends on available space. The component 
+adds `role='grid'` to the lightboard and `role='gridcell` to the individual slides.
+
+The Material Design Lite Ext (MDLEXT) lightboard has two versions; one version based on media queries and one version 
+based on **element queries**.
+
+### How to use the eq.js version of MDLEXT lightboard
+
+&nbsp;1. Install [eq.js](https://github.com/Snugug/eq.js).
+```sh
+$ npm install --save eq.js
+```
+
+&nbsp;2. Import `mdl-ext-eqjs.scss` in your main SASS file. Remove `mdl-ext.scss` - they can not co exist.
+```css
+@import '../node_modules/mdl-ext/src/mdl-ext-eqjs';
+```
+
+&nbsp;3. Import or Require `eq.js`.  
+```javascript
+const eqjs = require('eq.js'); // ... or:  import eqjs from 'eq.js';
+```
+
+&nbsp;4. Upgrade DOM and trigger `eq.js`<br/>
+If you're loading html fragments, using e.g. Ajax, then upgrade DOM and trigger `eq.js` after page load.
+
+```javascript
+window.fetch(href, {method: 'get'})
+ .then(response => response.text())
+ .then(text => {
+   contentPanelEl.insertAdjacentHTML('afterbegin', text);
+
+    // Upgrade DOM
+    componentHandler.upgradeDom();
+
+   // Trigger eq.js
+   eqjs.refreshNodes();
+   eqjs.query(undefined, true);
+})
+.catch(err => console.error(err));
+```
+
+An example of how to use `eq.js` in a SPA can be found [here](https://github.com/leifoolsen/mdl-webpack).                           
+
+## To include a MDLEXT lightboard component
+&nbsp;1. Code a `<ul>` element with `class="mdlext-lightboard mdlext-js-lightboard"` to hold the lightboard slides.
+```html
+<ul class="mdlext-lightboard mdlext-js-lightboard">
+</ul>
+```
+
+&nbsp;2. Code a `<li>` element with `class="mdlext-lightboard__slide"`  to hold an individual slide.
+```html
+<ul class="mdlext-lightboard mdlext-js-lightboard">
+  <li class="mdlext-lightboard__slide">
+  <li>
+</ul>
+```
+
+&nbsp;3. Code an `<a href="#">` element with `class="mdlext-lightboard__slide__frame"`  to hold the slide frame. Optionally add a href to a large version of the image shown in the slide.
+```html
+<ul class="mdlext-lightboard mdlext-js-lightboard">
+  <li class="mdlext-lightboard__slide">
+    <a href="#" class="mdlext-lightboard__slide__frame">
+    </a>  
+  <li>
+</ul>
+```
+
+&nbsp;4. Code a `<figure>` element (decorates frame and center image in slide).  
+```html
+<ul class="mdlext-lightboard mdlext-js-lightboard">
+  <li class="mdlext-lightboard__slide">
+    <a href="#" class="mdlext-lightboard__slide__frame">
+      <figure>
+      </figure>
+    </a>  
+  <li>
+</ul>
+```
+
+&nbsp;5. Inside the `<figure>` element add an `<img>` element with reference to the thumbnail image to be shown in slide. Optionally add a `<figcaption>` element to hold the image title.    
+```html
+<ul class="mdlext-lightboard mdlext-js-lightboard">
+  <li class="mdlext-lightboard__slide">
+    <a href="#" class="mdlext-lightboard__slide__frame">
+      <figure>
+        <img src="_D802591.jpg" title="Whooper swans in flight"/>
+        <figcaption>_D802591.jpg</figcaption>
+      </figure>
+    </a>  
+  <li>
+</ul>
+```
+
+&nbsp;6. Repeat steps 2..5 for each slide required.
+
+### Example
+Lightboard with eight slides, ripple effect on each slide, no spacing between slides, subscribes to lightboard `select` event.
+
+```html
+<ul id="lightboard-1" class="mdlext-lightboard mdlext-js-lightboard
+  mdlext-lightboard--no-spacing
+  mdl-js-ripple-effect mdl-js-ripple-effect--ignore-events">
+
+  <li class="mdlext-lightboard__slide">
+    <a href="#" class="mdlext-lightboard__slide__frame">
+      <figure>
+        <img src="_D802141.jpg" title="Northern goshawk with prey"/>
+        <figcaption>_D802141.jpg</figcaption>
+      </figure>
+    </a>
+  </li>
+  <li class="mdlext-lightboard__slide">
+    <a href="#" class="mdlext-lightboard__slide__frame">
+      <figure>
+        <img src="_D802591.jpg" title="Whooper swans in flight"/>
+        <figcaption>_D802591.jpg</figcaption>
+      </figure>
+    </a>
+  </li>
+  <li class="mdlext-lightboard__slide">
+    <a href="#" class="mdlext-lightboard__slide__frame">
+      <figure>
+        <img src="_D804370-3.jpg" title="European green woodpecker"/>
+        <figcaption>_D804370-3.jpg</figcaption>
+      </figure>
+    </a>
+  </li>
+  <li class="mdlext-lightboard__slide">
+    <a href="#" class="mdlext-lightboard__slide__frame">
+      <figure>
+        <img src="_D808689.jpg" title="The bridge"/>
+        <figcaption>_D808689.jpg</figcaption>
+      </figure>
+    </a>
+  </li>
+  <li class="mdlext-lightboard__slide">
+    <a href="#" class="mdlext-lightboard__slide__frame">
+      <figure>
+        <img src="_D802181.jpg" title="Landscape in blue pastel"/>
+        <figcaption>_D802181.jpg</figcaption>
+      </figure>
+    </a>
+  </li>
+  <li class="mdlext-lightboard__slide">
+    <a href="#" class="mdlext-lightboard__slide__frame">
+      <figure>
+        <img src="_D800912.jpg" title="Hiking the mountains of Dovre"/>
+        <figcaption>_D800912.jpg</figcaption>
+      </figure>
+    </a>
+  </li>
+  <li class="mdlext-lightboard__slide">
+    <a href="#" class="mdlext-lightboard__slide__frame">
+      <figure>
+        <img src="_D809453-_D809457-4.jpg" title="Train to nowhwere. Ny Aalesund, Spitsbergen." />
+        <figcaption>_D809453-_D809457-4.jpg</figcaption>
+      </figure>
+    </a>
+  </li>
+  <li class="mdlext-lightboard__slide">
+    <a href="#" class="mdlext-lightboard__slide__frame">
+      <figure>
+        <img src="_DSC8214.jpg" title="Blues"/>
+        <figcaption>_DSC8214.jpg</figcaption>
+      </figure>
+    </a>
+  </li>
+</ul>
+
+<script>
+  window.addEventListener('load', function() {
+    var lightboard = document.querySelector('#lightboard-1');
+    lightboard.addEventListener('select', function(e) {
+      console.log('Slide selected. Source:', e.detail.source);
+    });
+  });
+</script>
+```
+
+## Keyboard interaction
+The lightboard interacts with the following keyboard keys.
+
+*   `Tab` - When focus is on a slide, pressing the `Tab` key moves focus in the following manner:
+    1.  If interactive glyphs or menus are present in the slide frame, focus moves to each in order. (Not implemented yet)
+    2.  The next `Tab` key press moves focus as follows:
+        *   If there is a next slide, focus moves to the next slide.
+        *   If focus is on the last slide, focus moves to the first focusable element outside the lightboard component.
+*   `Left arrow` - Moves focus to the previous slide. If the current slide is the first slide, focus moves to the last slide.
+*   `Right arrow` - Moves focus to the next slide. If the current slide is the last slide, focus moves to the first slide.
+*   `Up arrow` - behaves the same as left arrow.
+*   `Down arrow` - behaves the same as right arrow.
+*   `End` - When focus is on a slide, an `End` key press moves focus to the last slide.
+*   `Home` - When focus is on a slide, a `Home` key press moves focus to the first slide.
+*   `Enter/Space` - When focus is on slide, pressing `Enter`/`Space` selects that particular slide. The lightboard emits a **select** event.
+*   `Shift+Tab` - Generally the reverse of `Tab`.
+
+
+## Events
+Interaction with the component programmatically is performed receiving events from the component or by sending events to 
+the component (or by using the public api).  
+
+### Events the component listenes to
+A client can send a `command` custom event to the lightboard. The command event holds a detail object defining the action 
+to perform and a optionally a target for the action.
+
+The detail object has the following structure:
+
+```javascript
+detail: { 
+  action, // "first", "last", "next", "prev", "upgrade" or "select" 
+  target  // Target, the slide that should be affected by the event 
+}
+```
+
+Possible actions are:
+
+#### first
+Focuses the first slide.
+
+```javascript
+myLightboard = document.querySelector('#my-lightboard');
+ce = new CustomEvent('command', { detail: { action : 'first' } });
+myLightboard.dispatchEvent(ce);
+```
+
+#### last
+Focuses the last slide.
+
+```javascript
+myLightboard = document.querySelector('#my-lightboard');
+ce = new CustomEvent('command', { detail: { action : 'last' } });
+myLightboard.dispatchEvent(ce);
+```
+
+#### next
+Focuses the next slide.
+
+```javascript
+myLightboard = document.querySelector('#my-lightboard');
+ce = new CustomEvent('command', { detail: { action : 'next' } });
+myLightboard.dispatchEvent(ce);
+```
+
+#### prev
+Focuses the previous slide.
+
+```javascript
+myLightboard = document.querySelector('#my-lightboard');
+ce = new CustomEvent('command', { detail: { action : 'prev' } });
+myLightboard.dispatchEvent(ce);
+```
+
+#### select
+Selects a slide, i.e. adds `aria-selected="true"` on the targeted slide. The lightboard responds with a `select` event.
+
+```javascript
+myLightboard = document.querySelector('#my-lightboard');
+slide = lightboard.querySelector('.mdlext-lightboard__slide:nth-child(2)');
+ce = new CustomEvent('command', { detail: { action : 'prev', target: slide } });
+myLightboard.dispatchEvent(ce);
+```
+
+#### upgrade
+Upgrade slides. If you add slides to the lightboard after the page has loaded, you must call `upgrade` to 
+notify the lightboard component about the new slides.
+
+```javascript
+myLightboard = document.querySelector('#my-lightboard');
+slide = 
+   '<li class="mdlext-lightboard__slide">'
+  +'  <a href="#" class="mdlext-lightboard__slide__frame">'
+  +'    <figure>'
+  +'      <img src="_D802181.jpg" title="Landscape in blue pastel"/>'
+  +'      <figcaption>_D802181.jpg</figcaption>'
+  +'    </figure>'
+  +'  </a>'
+  +'</li>';
+
+myLightboard.insertAdjacentHTML('beforeend', slide);
+ce = new CustomEvent('command', { detail: { action : 'upgrade' } });
+myLightboard.dispatchEvent(ce);
+```
+
+### Events emitted from the component
+The lightboard emits a custom `select` event when a slide is clicked. The event has a detail object with the following content:
+```
+{
+  source  // the slide instance that caused the event
+}
+```
+
+Set up an event listener to receive the select event.
+```javascript
+document.querySelector('#my-lightboard').addEventListener('select', function(e) {
+  console.log('Slide selected:', e.detail.source);
+});
+```
+
+Trigger the event.
+```javascript
+myLightboard = document.querySelector('#my-lightboard');
+slide = lightboard.querySelector('.mdlext-lightboard__slide:nth-child(2)');
+ce = new CustomEvent('command', { detail: { action : 'select', target: slide } });
+myLightboard.dispatchEvent(ce);
+```
+
+## Public methods
+
+### upgradeSlides()
+Upgrade slides. If you add slides to the lightboard after the page has loaded, you must call `upgradeSlides` to 
+notify the component about the new slides.
+
+```javascript
+slide = 
+   '<li class="mdlext-lightboard__slide">'
+  +'  <a href="#" class="mdlext-lightboard__slide__frame">'
+  +'    <figure>'
+  +'      <img src="_D802181.jpg" title="Landscape in blue pastel"/>'
+  +'      <figcaption>_D802181.jpg</figcaption>'
+  +'    </figure>'
+  +'  </a>'
+  +'</li>';
+
+myLightboard = document.querySelector('#my-lightboard');
+myLightboard.insertAdjacentHTML('beforeend', slide);
+myLightboard.MaterialExtLightboard.upgradeSlides();
+```
+
+### command( detail )
+Executes an action, optionally targeting a specific slide. The actions corresponds to the custom events defined for this 
+component.
+ 
+The detail object parameter has the following structure:
+```javascript
+detail: { 
+  action, // "first", "last", "next", "prev", "upgrade" or "select" 
+  target  // Target, the slide that should be affected by the event 
+}
+```
+
+Possible actions are:
+
+#### first: command( {action: 'first' } )
+Focuses the first slide.
+
+```javascript
+myLightboard = document.querySelector('#my-lightboard');
+myLightboard.MaterialExtLightboard.command( {action: 'first'} );
+```
+
+#### last: command( {action: 'last' } )
+Focuses the last slide.
+
+```javascript
+myLightboard = document.querySelector('#my-lightboard');
+myLightboard.MaterialExtLightboard.command( {action: 'last'} );
+```
+
+#### next: command( {action: 'next' } )
+Focuses the next slide.
+
+```javascript
+myLightboard = document.querySelector('#my-lightboard');
+myLightboard.MaterialExtLightboard.command( {action: 'next'} );
+```
+
+#### prev: command( {action: 'prev' } )
+Focuses the previous slide.
+
+```javascript
+myLightboard = document.querySelector('#my-lightboard');
+myLightboard.MaterialExtLightboard.command( {action: 'prev'} );
+```
+
+#### select: command( {action: 'first', target: slide } )
+Selects a slide, i.e. adds `aria-selected="true"` on the targeted slide. The lightboard responds with a `select` event.
+
+```javascript
+myLightboard = document.querySelector('#my-lightboard');
+slide = lightboard.querySelector('.mdlext-lightboard__slide:nth-child(2)');
+myLightboard.MaterialExtLightboard.command( {action: 'prev', target: slide} );
+```
+
+#### upgrade: command( {action: 'upgrade' } )
+Upgrade slides. If you add slides to the lightboard after the page has loaded, you must call `upgrade` to 
+notify the lightboard component about the new slides.
+
+```javascript
+myLightboard = document.querySelector('#my-lightboard');
+slide = 
+   '<li class="mdlext-lightboard__slide">'
+  +'  <a href="#" class="mdlext-lightboard__slide__frame">'
+  +'    <figure>'
+  +'      <img src="_D802181.jpg" title="Landscape in blue pastel"/>'
+  +'      <figcaption>_D802181.jpg</figcaption>'
+  +'    </figure>'
+  +'  </a>'
+  +'</li>';
+
+myLightboard.insertAdjacentHTML('beforeend', slide);
+myLightboard.MaterialExtLightboard.command( {action: 'upgrade'} );
+```
+
+## Configuration options
+
+The MDLEXT CSS classes apply various predefined visual and behavioral enhancements to the lightboard.
+The table below lists the available classes and their effects.
+
+| MDLEXT class | Effect | Remarks |
+|--------------|--------|---------|
+| `mdlext-lightboard` | Defines a container as an MDLEXT lightboard component | Required on `<ul>` element |
+| `mdlext-js-lightboard` | Assigns basic MDL behavior to lightboard | Required on `<ul>` element |
+| `mdlext-lightboard--no-spacing` | Modifies the slides to have no margin between them. | Optional on `<ul>` element |
+| `mdlext-lightboard__slide` | Defines a slide | Required on `<li>` element |
+| `mdlext-lightboard__slide__frame` | Defines the slide frame, makes the frame focusable and selectable | Required on `<a>` element. First inner element of `<li>`  |
+| `mdl-js-ripple-effect` | Applies ripple click effect to slides | Optional; goes on "outer" `<ul>` element |
+| `mdl-js-ripple-effect--ignore-events` |  | Should be added when the component initializes, but that does not seem to happen due to bug/limitation in MDL. For now, add this class if `mdl-js-ripple-effect` class is applied |
+
+
+A lightboard and its assosiated slides has the following roles.
+
+| Attribute | Effect | Remarks |
+|-----------|--------|---------|
+| `role="grid"` | Defines the lightboard as a WAI-ARIA grid | Added to `mdlext-lightboard` when component innitializes |
+| `role="gridcell"` | Defines the slide as a WAI-ARIA cell | Added to `mdlext-lightboard__slide` when component innitializes |
+| `aria-selected` | Defines a slide as selected | Added to `mdlext-lightboard__slide` when a slide is clicked |
+
+
+## How to use the component programmatically
+Refer to [snippets/lightboard.html](./snippets/lightboard.html) or the [tests](../../test/lightboard/lightboard.spec.js) 
+for detailed usage.
diff --git a/node_modules/mdl-ext/src/lightboard/snippets/lightboard.html b/node_modules/mdl-ext/src/lightboard/snippets/lightboard.html
new file mode 100644
index 0000000..555a4d8
--- /dev/null
+++ b/node_modules/mdl-ext/src/lightboard/snippets/lightboard.html
@@ -0,0 +1,174 @@
+<p style="margin-bottom:32px;">A lightboard is a translucent surface illuminated from behind, used for
+  situations where a shape laid upon the surface needs to be seen with high contrast. In the "old days"
+  of photography photograpers used a lightboard to get a quick view of, sorting and organizing their slides.
+</p>
+
+<ul id="lightboard-1" class="mdlext-lightboard mdlext-js-lightboard mdl-js-ripple-effect mdl-js-ripple-effect--ignore-events">
+  <li class="mdlext-lightboard__slide">
+    <a href="#" class="mdlext-lightboard__slide__frame">
+      <figure>
+        <img src="./images/_D802141.jpg" title="Northern goshawk with prey"/>
+        <figcaption>_D802141.jpg</figcaption>
+      </figure>
+    </a>
+  </li>
+  <li class="mdlext-lightboard__slide">
+    <a href="#" class="mdlext-lightboard__slide__frame">
+      <figure>
+        <img src="./images/_D802591.jpg" title="Whooper swans in flight"/>
+        <figcaption>_D802591.jpg</figcaption>
+      </figure>
+    </a>
+  </li>
+  <li class="mdlext-lightboard__slide">
+    <a href="#" class="mdlext-lightboard__slide__frame">
+      <figure>
+        <img src="./images/_D804370-3.jpg" title="European green woodpecker"/>
+        <figcaption>_D804370-3.jpg</figcaption>
+      </figure>
+    </a>
+  </li>
+  <li class="mdlext-lightboard__slide">
+    <a href="#" class="mdlext-lightboard__slide__frame">
+      <figure>
+        <img src="./images/_D808689.jpg" title="The bridge"/>
+        <figcaption>_D808689.jpg</figcaption>
+      </figure>
+    </a>
+  </li>
+  <li class="mdlext-lightboard__slide">
+    <a href="#" class="mdlext-lightboard__slide__frame">
+      <figure>
+        <img src="./images/_D802181.jpg" title="Landscape in blue pastel"/>
+        <figcaption>_D802181.jpg</figcaption>
+      </figure>
+    </a>
+  </li>
+  <li class="mdlext-lightboard__slide">
+    <a href="#" class="mdlext-lightboard__slide__frame">
+      <figure>
+        <img src="./images/_D800912.jpg" title="Hiking the mountains of Dovre"/>
+        <figcaption>_D800912.jpg</figcaption>
+      </figure>
+    </a>
+  </li>
+  <li class="mdlext-lightboard__slide">
+    <a href="#" class="mdlext-lightboard__slide__frame">
+      <figure>
+        <img src="./images/_D809453-_D809457-4.jpg" title="Train to nowhwere. Ny Aalesund, Spitsbergen." />
+        <figcaption>_D809453-_D809457-4.jpg</figcaption>
+      </figure>
+    </a>
+  </li>
+  <li class="mdlext-lightboard__slide">
+    <a href="#" class="mdlext-lightboard__slide__frame">
+      <figure>
+        <img src="./images/_DSC8214.jpg" title="Blues"/>
+        <figcaption>_DSC8214.jpg</figcaption>
+      </figure>
+    </a>
+  </li>
+  <li class="mdlext-lightboard__slide">
+    <a href="#" class="mdlext-lightboard__slide__frame">
+      <figure>
+        <img src="./images/_D800017.jpg" />
+        <figcaption>_D800017.jpg</figcaption>
+      </figure>
+    </a>
+  </li>
+  <li class="mdlext-lightboard__slide">
+    <a href="#" class="mdlext-lightboard__slide__frame">
+      <figure>
+        <img src="./images/_D800023.jpg" />
+        <figcaption>_D800023.jpg</figcaption>
+      </figure>
+    </a>
+  </li>
+  <li class="mdlext-lightboard__slide">
+    <a href="#" class="mdlext-lightboard__slide__frame">
+      <figure>
+        <img src="./images/_D800851.jpg" />
+        <figcaption>_D800851.jpg</figcaption>
+      </figure>
+    </a>
+  </li>
+  <li class="mdlext-lightboard__slide">
+    <a href="#" class="mdlext-lightboard__slide__frame">
+      <figure>
+        <img src="./images/_D800166.jpg" />
+      </figure>
+    </a>
+  </li>
+  <li class="mdlext-lightboard__slide">
+    <a href="#" class="mdlext-lightboard__slide__frame">
+      <figure>
+        <img src="./images/_D800951.jpg" />
+      </figure>
+    </a>
+  </li>
+  <li class="mdlext-lightboard__slide">
+    <a href="#" class="mdlext-lightboard__slide__frame">
+      <figure>
+        <img src="./images/_D801188.jpg" />
+      </figure>
+    </a>
+  </li>
+  <li class="mdlext-lightboard__slide">
+    <a href="#" class="mdlext-lightboard__slide__frame">
+      <figure>
+        <img src="./images/_D801205-2.jpg" />
+      </figure>
+    </a>
+  </li>
+  <li class="mdlext-lightboard__slide">
+    <a href="#" class="mdlext-lightboard__slide__frame">
+      <figure>
+        <img src="./images/_D801274.jpg" />
+      </figure>
+    </a>
+  </li>
+  <li class="mdlext-lightboard__slide">
+    <a href="#" class="mdlext-lightboard__slide__frame">
+      <figure>
+        <img src="./images/_D801392.jpg" />
+      </figure>
+    </a>
+  </li>
+  <li class="mdlext-lightboard__slide">
+    <a href="#" class="mdlext-lightboard__slide__frame">
+      <figure>
+        <img src="./images/_D801952-4.jpg" />
+      </figure>
+    </a>
+  </li>
+  <li class="mdlext-lightboard__slide">
+    <a href="#" class="mdlext-lightboard__slide__frame">
+      <figure>
+        <img src="./images/_D807603.jpg" />
+      </figure>
+    </a>
+  </li>
+  <li class="mdlext-lightboard__slide">
+    <a href="#" class="mdlext-lightboard__slide__frame">
+      <figure>
+        <img src="./images/_D807689.jpg" />
+      </figure>
+    </a>
+  </li>
+</ul>
+
+<p class="mdl-typography--caption" style="margin-top: 32px;">
+  All images appearing in this page are the exclusive property of Leif Olsen and are protected under the United States and International Copyright laws.
+  The images may not be reproduced or manipulated without the written permission of Leif Olsen.
+  Use of any image as the basis for another photographic concept or illustration (digital, artist rendering or alike) is a violation of the United States and International Copyright laws.
+  All images are copyrighted &copy; Leif Olsen, 2016.
+</p>
+
+<script>
+  window.addEventListener('load', function() {
+    var lightboard = document.querySelector('#lightboard-1');
+    lightboard.addEventListener('select', function(e) {
+      console.log('Slide selected. Source:', e.detail.source);
+    });
+  });
+</script>
diff --git a/node_modules/mdl-ext/src/lightbox/_lightbox.scss b/node_modules/mdl-ext/src/lightbox/_lightbox.scss
new file mode 100644
index 0000000..721d181
--- /dev/null
+++ b/node_modules/mdl-ext/src/lightbox/_lightbox.scss
@@ -0,0 +1,141 @@
+@charset "UTF-8";
+
+/**
+ * Copyright 2016 Leif Olsen. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// Use of this module requires the user to include variables from material-design-lite
+//@import "../../node_modules/material-design-lite/src/variables";
+//@import "../../node_modules/material-design-lite/src/mixins";
+@import "../variables";
+
+.mdlext-lightbox {
+  user-select: none;
+  cursor: default;
+  position: relative;
+  width: auto;
+  max-width: 100%;
+  margin: 0 auto;
+  border: $mdlext-lightbox-border;
+  border-radius: $mdlext-lightbox-border-radius;
+  background-color: $mdlext-lightbox-background-color;
+  box-sizing: border-box;
+  outline: 0;
+  display: block; // display: flex and IE11 has issues with reposition. Set display:block for now.
+
+  *,
+  *::before,
+  *::after,
+  input[type="search"] {
+    box-sizing: border-box;
+  }
+
+  .mdlext-lightbox__slider {
+    // Displays prevvious, current and next image while dragging
+    // Elements are created by lightbox component when dragging starts
+    position: absolute;
+    top: 0;
+    left: 0;
+    display: flex;
+    justify-content: center;
+
+    .mdlext-lightbox__slider__slide {
+      flex-shrink: 0;
+      display: block;
+      text-align: left;
+      color: #7f7f7f;
+      background-size: cover;
+      background-position: center;
+      background-repeat: no-repeat;
+
+      //&:nth-child(1),
+      //&:nth-child(3) {
+      //  filter: blur(1px);
+      //}
+    }
+  }
+
+  figure {
+    margin: $mdlext-lightbox-figure-margin;
+    padding: $mdlext-lightbox-figure-padding;
+    position: relative;
+
+    img {
+      width: 100%;
+      max-width: 100%;
+      height: auto;
+      border: 0;
+      outline: 0;
+    }
+    figcaption {
+      @include typo-caption($colorContrast: false, $usePreferred: true);
+
+      display: block;
+      position: absolute;
+      bottom: 0;
+      left: 0;
+      right: 0;
+      max-width: 100%;
+      height: auto;
+      max-height: 50%;
+      overflow: auto;
+      padding: 8px;
+      background-color: $mdlext-lightbox-figcaption-background-color;
+      transform-origin: bottom;
+      transform: scaleY(0);
+      transition: 0.2s ease-in-out;
+
+      &.mdlext-lightbox__show-figcaption {
+        transform: scaleY(1);
+      }
+      tbody {
+        th {
+          text-align: left;
+        }
+        th,
+        td {
+          vertical-align: text-top;
+        }
+      }
+    }
+  }
+  .mdl-card__menu {
+    color: #ffffff;
+    z-index: 1;
+  }
+  footer {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    background-color: $mdlext-lightbox-footer-background-color;
+
+    .mdl-card__supporting-text {
+      flex: 1;
+      overflow: hidden;
+      padding: 0;
+      height: $card-supporting-text-line-height;
+      width: 100%;
+    }
+    nav {
+      display: flex;
+    }
+  }
+
+  &.mdlext-lightbox--sticky-footer footer {
+    position: fixed;
+    bottom: 0;
+    left: 0;
+  }
+}
diff --git a/node_modules/mdl-ext/src/lightbox/lightbox.js b/node_modules/mdl-ext/src/lightbox/lightbox.js
new file mode 100644
index 0000000..2e14463
--- /dev/null
+++ b/node_modules/mdl-ext/src/lightbox/lightbox.js
@@ -0,0 +1,359 @@
+/**
+ * @license
+ * Copyright 2016 Leif Olsen. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * This code is built with Google Material Design Lite,
+ * which is Licensed under the Apache License, Version 2.0
+ */
+
+
+/**
+ * Responsive Lightbox
+ */
+
+import fullThrottle from '../utils/full-throttle';
+import {
+  VK_ESC,
+  VK_SPACE,
+  VK_END,
+  VK_HOME,
+  VK_ARROW_LEFT,
+  VK_ARROW_UP,
+  VK_ARROW_RIGHT,
+  VK_ARROW_DOWN,
+  IS_UPGRADED
+} from '../utils/constants';
+
+(function() {
+  'use strict';
+
+  const LIGHTBOX = 'mdlext-lightbox';
+  const LIGHTBOX_SLIDER = 'mdlext-lightbox__slider';
+  const LIGHTBOX_SLIDER_SLIDE = 'mdlext-lightbox__slider__slide';
+  const STICKY_FOOTER = 'mdlext-lightbox--sticky-footer';
+  const BUTTON = 'mdl-button';
+
+  /**
+   * https://github.com/google/material-design-lite/issues/4205
+   * @constructor
+   * @param {Element} element The element that will be upgraded.
+   */
+  const MaterialExtLightbox = function MaterialExtLightbox(element) {
+    // Stores the element.
+    this.element_ = element;
+
+    // Initialize instance.
+    this.init();
+  };
+  window['MaterialExtLightbox'] = MaterialExtLightbox;
+
+
+  /**
+   * Handle keypress
+   * @param event
+   * @private
+   */
+  MaterialExtLightbox.prototype.keyDownHandler_ = function(event) {
+
+    if (event) {
+      if ( event.keyCode === VK_ESC || event.keyCode === VK_SPACE
+        || event.keyCode === VK_END || event.keyCode === VK_HOME
+        || event.keyCode === VK_ARROW_UP || event.keyCode === VK_ARROW_LEFT
+        || event.keyCode === VK_ARROW_DOWN || event.keyCode === VK_ARROW_RIGHT) {
+
+        if(event.keyCode !== VK_ESC) {
+          event.preventDefault();
+          event.stopPropagation();
+        }
+
+        let action = 'first';
+        if (event.keyCode === VK_END) {
+          action = 'last';
+        }
+        else if (event.keyCode === VK_ARROW_UP || event.keyCode === VK_ARROW_LEFT) {
+          action = 'prev';
+        }
+        else if (event.keyCode === VK_ARROW_DOWN || event.keyCode === VK_ARROW_RIGHT) {
+          action = 'next';
+        }
+        else if (event.keyCode === VK_SPACE) {
+          action = 'select';
+        }
+        else if (event.keyCode === VK_ESC) {
+          action = 'cancel';
+        }
+
+        dispatchAction_(action, this);
+      }
+    }
+  };
+
+  /**
+   * Handle button clicks
+   * @param event
+   * @private
+   */
+  MaterialExtLightbox.prototype.buttonClickHandler_ = function(event) {
+
+    if (event) {
+      event.preventDefault();
+      event.stopPropagation();
+
+      dispatchAction_(this.getAttribute('data-action') || '', this);
+
+      const n = this.closest(`.${LIGHTBOX}`);
+      if(n) {
+        n.focus();
+      }
+    }
+  };
+
+  /**
+   * Dispatches an action custom event
+   * @param action
+   * @param source
+   * @param target
+   * @private
+   */
+  const dispatchAction_ = (action, source, target = source) => {
+
+    target.dispatchEvent(new CustomEvent('action', {
+      bubbles: true,
+      cancelable: true,
+      detail: {
+        action: action || '',
+        source: source
+      }
+    }));
+  };
+
+  /**
+   * Reposition dialog if component parent element is "DIALOG"
+   * @param lightboxElement
+   * @private
+   */
+  const repositionDialog_ = lightboxElement => {
+    const footerHeight = (footer, isSticky) => isSticky && footer ? footer.offsetHeight : 0;
+
+    const reposition = (dialog, fh) => {
+      if (window.getComputedStyle(dialog).position === 'absolute') {
+        const scrollTop = document.body.scrollTop || document.documentElement.scrollTop;
+        const topValue = scrollTop + (window.innerHeight - dialog.offsetHeight - fh) / 2;
+        dialog.style.top = `${Math.max(scrollTop, topValue)}px`;
+      }
+    };
+
+    const p = lightboxElement.parentNode;
+    const dialog = p && p.nodeName === 'DIALOG' ? p : null;
+
+    if(dialog && dialog.hasAttribute('open')) {
+      lightboxElement.style.width = 'auto';
+      lightboxElement.style.maxWidth = '100%';
+      const img = lightboxElement.querySelector('img');
+      if(img) {
+        lightboxElement.style.maxWidth = img.naturalWidth !== undefined ? `${img.naturalWidth}px` : `${img.width}px` || '100%';
+      }
+
+      const fh = footerHeight(lightboxElement.querySelector('footer'), lightboxElement.classList.contains(STICKY_FOOTER));
+      const vh = Math.max(document.documentElement.clientHeight, window.innerHeight || 0) - fh;
+      if (dialog.offsetHeight > vh) {
+        let n = 0;
+        while(dialog.offsetHeight > vh && ++n < 4) {
+          lightboxElement.style.width = `${lightboxElement.offsetWidth * vh / lightboxElement.offsetHeight}px`;
+        }
+      }
+      reposition(dialog, fh);
+    }
+  };
+
+  /**
+   * Handle image load
+   * @param event
+   * @private
+   */
+
+  MaterialExtLightbox.prototype.imgLoadHandler_ = function( /*event*/ ) {
+    repositionDialog_(this);
+  };
+
+
+  /**
+   * Handle image drag
+   * @param event
+   * @private
+     */
+  MaterialExtLightbox.prototype.imgDragHandler_ = function(event ) {
+
+    const setStyles = ( element, properties ) => {
+      //noinspection JSAnnotator
+      for(const [key, value] of Object.entries(properties)) {
+        element.style[key] = value;
+      }
+      // ... or:
+      //for (const key in properties) {
+      //  element.style[key] = properties[key];
+      //}
+    };
+
+    event.preventDefault();
+    //event.stopPropagation();
+
+    const x = event.clientX || (event.touches !== undefined ? event.touches[0].clientX : 0);
+
+    const img = this;
+    img.style.opacity = '0.2';
+
+    const slider = document.createElement('div');
+    slider.classList.add(LIGHTBOX_SLIDER);
+    setStyles(slider, {'width': `${img.offsetWidth}px`, 'height': `${img.offsetHeight}px`} );
+
+    let slide  = document.createElement('div');
+    slide.classList.add(LIGHTBOX_SLIDER_SLIDE);
+    slide.textContent = '>';
+    setStyles(slide, {
+      'width'           : `${img.offsetWidth}px`,
+      'height'          : `${img.offsetHeight}px`,
+      'line-height'     : `${img.offsetHeight}px`,
+      'font-size'       : `${img.offsetHeight/4}px`,
+      'text-align'      : 'right',
+      'background-image': `url("${img.getAttribute('data-img-url-prev') || ''}")`
+    });
+    slider.appendChild(slide);
+
+    slide  = document.createElement('div');
+    slide.classList.add(LIGHTBOX_SLIDER_SLIDE);
+    setStyles(slide, {
+      'width'           : `${img.offsetWidth}px`,
+      'height'          : `${img.offsetHeight}px`,
+      'background-image': `url("${img.src}")`
+    });
+    slider.appendChild(slide);
+
+    slide  = document.createElement('div');
+    slide.classList.add(LIGHTBOX_SLIDER_SLIDE);
+    slide.textContent = '<';
+    setStyles(slide, {
+      'width'           : `${img.offsetWidth}px`,
+      'height'          : `${img.offsetHeight}px`,
+      'line-height'     : `${img.offsetHeight}px`,
+      'font-size'       : `${img.offsetHeight/4}px`,
+      'text-align'      : 'left',
+      'background-image': `url("${img.getAttribute('data-img-url-next') || ''}")`
+    });
+    slider.appendChild(slide);
+
+    img.parentNode.appendChild(slider);
+
+
+    // drag handler
+    const drag = e => {
+      e.preventDefault();
+      const dx = (e.clientX || (e.touches !== undefined ? e.touches[0].clientX : 0)) - x; // TODO: maybe rewrite to improve performance
+
+      if(slider.offsetWidth - Math.abs(dx) > 19) {
+        slider.style.left = `${dx}px`;
+      }
+    };
+
+    // end drag handler
+    const endDrag = e => {
+      e.preventDefault();
+      //e.stopPropagation();
+
+      window.removeEventListener('mousemove', drag);
+      window.removeEventListener('touchmove', drag);
+      window.removeEventListener('mouseup', endDrag);
+      window.removeEventListener('touchend', endDrag);
+
+      const dx = slider.offsetLeft;
+      img.parentNode.removeChild(slider);
+      img.style.opacity = '1.0';
+
+      if(Math.abs(dx) > 19) {
+        dispatchAction_( (dx > 0 ? 'prev' : 'next') , img);
+      }
+    };
+
+    window.addEventListener('mousemove', drag);
+    window.addEventListener('touchmove', drag);
+    window.addEventListener('mouseup', endDrag);
+    window.addEventListener('touchend',endDrag);
+  };
+
+
+  /**
+   * Initialize component
+   */
+  MaterialExtLightbox.prototype.init = function() {
+
+    if (this.element_) {
+      // Do the init required for this component to work
+      this.element_.addEventListener('keydown', this.keyDownHandler_.bind(this.element_), true);
+
+      if(!Number.isInteger(this.element_.getAttribute('tabindex'))) {
+        this.element_.setAttribute('tabindex', 1);
+      }
+
+      [...this.element_.querySelectorAll(`.${BUTTON}`)].forEach( button =>
+        button.addEventListener('click', this.buttonClickHandler_.bind(button), false)
+      );
+
+      const figcaption = this.element_.querySelector('figcaption');
+      if(figcaption) {
+        figcaption.addEventListener('click', this.buttonClickHandler_.bind(figcaption), false);
+      }
+
+      const footer = this.element_.querySelector('footer');
+      if(footer) {
+        footer.addEventListener('click', this.buttonClickHandler_.bind(footer), false);
+      }
+
+      const img = this.element_.querySelector('img');
+      if(img) {
+        img.addEventListener('load', this.imgLoadHandler_.bind(this.element_), false);
+        img.addEventListener('click', e => e.preventDefault(), true);
+        img.addEventListener('mousedown', this.imgDragHandler_.bind(img), true);
+        img.addEventListener('touchstart', this.imgDragHandler_.bind(img), true);
+      }
+      window.addEventListener('resize', fullThrottle( () => repositionDialog_(this.element_) ));
+      window.addEventListener('orientationchange', () => repositionDialog_(this.element_));
+
+      // Set upgraded flag
+      this.element_.classList.add(IS_UPGRADED);
+    }
+  };
+
+  /*
+   * Downgrade component
+   * E.g remove listeners and clean up resources
+   *
+   * Nothing to downgrade
+   *
+  MaterialExtLightbox.prototype.mdlDowngrade_ = function() {
+  };
+  */
+
+  /**
+   * The component registers itself. It can assume componentHandler is available in the global scope.
+   */
+  /* jshint undef:false */
+  componentHandler.register({
+    constructor: MaterialExtLightbox,
+    classAsString: 'MaterialExtLightbox',
+    cssClass: 'mdlext-js-lightbox'
+  });
+
+})();
+
diff --git a/node_modules/mdl-ext/src/lightbox/readme.md b/node_modules/mdl-ext/src/lightbox/readme.md
new file mode 100644
index 0000000..5744920
--- /dev/null
+++ b/node_modules/mdl-ext/src/lightbox/readme.md
@@ -0,0 +1,322 @@
+# Lightbox
+
+![Lightbox](../../etc/lightbox.png)
+A responsive lightbox to be used in conjunction with e.g. a MDLEXT lightboard component.
+
+## Introduction
+The Material Design Lite Ext (MDLEXT) Lightbox displays an image filling the screen, and dimming out the rest of the web page.
+It acts as a modal dialog, using the `<dialog>` element as a container for the lightbox. The component uses 
+the [Material Design Lite Card component](http://www.getmdl.io/components/index.html#cards-section) to provide a layout for the lightbox.
+
+## How to use the Google Chrome Dialog polyfill 
+
+&nbsp;1. Install [Google Chrome Dialog polyfill](https://github.com/GoogleChrome/dialog-polyfill).
+```sh
+$ npm install --save dialog-polyfill
+```
+
+&nbsp;2. Use the polyfill in a static page.
+```html
+<!DOCTYPE html>
+<html>
+<head>
+  <title>Material Design Lite Extensions</title>
+  <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:regular,bold,italic,thin,light,bolditalic,black,medium&amp;lang=en">
+  <link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
+  <link rel="stylesheet" href="node_modules/dialog-polyfill/dialog-polyfill.css" />
+  <link rel="stylesheet" href="node_modules/material-design-lite/material.css" />
+  <link rel="stylesheet" href="node_modules/mdl-ext/lib/mdl-ext.min.css" />
+</head>
+<body>
+<div class="mdl-layout mdl-js-layout mdl-layout--fixed-drawer">
+  <main class="mdl-layout__content">
+  </main
+</div>
+<script type="text/javascript" src="node_modules/dialog-polyfill/dialog-polyfill.js" charset="utf-8"></script>
+<script type="text/javascript" src="node_modules/material-design-lite/material.min.js" charset="utf-8"></script>
+<script type="text/javascript" src="node_modules/mdl-ext/lib/mdl-ext.min.js" charset="utf-8"></script>
+</body>
+</html>
+```
+
+&nbsp;3. Use it in your (Webpack) build.
+
+&nbsp;3.1. Import `dialog-polyfill.css` in your main SASS file..
+```css
+@import '../node_modules/dialog-polyfill/dialog-polyfill.css';
+```
+
+&nbsp;3.2. Require `dialog-polyfill`.  
+```javascript
+const dialogPolyfill = require('dialog-polyfill/dialog-polyfill');
+```
+
+&nbsp;... or import the `dialog-polyfill`.  
+```javascript
+import { dialogPolyfill }  from 'dialog-polyfill/dialog-polyfill';
+```
+
+>Adjust path to `node_modules` (libraries) according to where your files are located. 
+>For more information about the dialog polyfill, refer to the [Google Chrome Dialog polyfill](https://github.com/GoogleChrome/dialog-polyfill) documentaion and the Material Design Lite [Dialog](http://www.getmdl.io/components/index.html#dialog-section) section.
+
+## To include a MDLEXT lightbox component
+&nbsp;1. Code a `<dialog>` element with `class="mdlext-dialog"` to display the lightbox as a modal dialog.
+```html
+<dialog class="mdlext-dialog">
+</dialog>
+```
+
+&nbsp;2. Code a `<div>` element with `class="mdlext-lightbox mdlext-js-lightbox mdl-card"` to hold the lightbox.
+```html
+<dialog class="mdlext-dialog">
+  <div class="mdlext-lightbox mdlext-js-lightbox mdl-card">
+  </div>
+</dialog>
+```
+
+&nbsp;3. Code a `<div>` element with `class="mdl-card__menu mdl-color-text--white mdl-typography--body-2-color-contrast"` to hold the close dialog button.
+```html
+<dialog class="mdlext-dialog">
+  <div class="mdlext-lightbox mdlext-js-lightbox mdl-card">
+    <div class="mdl-card__menu mdl-color-text--white mdl-typography--body-2-color-contrast">
+    </div>
+  </div>
+</dialog>
+```
+
+&nbsp;4. Code a `<button>` element with `data-action="close"` and `class="mdl-button mdl-button--icon mdl-js-button mdl-js-ripple-effect"` to display the close button. Add an `<i>` element inside the `<button>` element to hold the close icon.
+```html
+<dialog class="mdlext-dialog">
+  <div class="mdlext-lightbox mdlext-js-lightbox mdl-card">
+    <div class="mdl-card__menu mdl-color-text--white mdl-typography--body-2-color-contrast">
+      <button data-action="close" class="mdl-button mdl-button--icon mdl-js-button mdl-js-ripple-effect" title="Close">
+        <i class="material-icons">close</i>
+      </button>
+    </div>
+  </div>
+</dialog>
+```
+
+&nbsp;5. Code a `<figure>` element with `class="mdl-card__media"` to hold the image and the image description.
+```html
+<dialog class="mdlext-dialog">
+  <div class="mdlext-lightbox mdlext-js-lightbox mdl-card">
+    <div class="mdl-card__menu mdl-color-text--white mdl-typography--body-2-color-contrast">
+      <button data-action="close" class="mdl-button mdl-button--icon mdl-js-button mdl-js-ripple-effect" title="Close">
+        <i class="material-icons">close</i>
+      </button>
+    </div>
+    <figure class="mdl-card__media">
+    </figure>
+  </div>
+</dialog>
+```
+
+&nbsp;5. Inside the `<figure>` element code an empty `<img>` element and an empty `<figcaption>` element to hold the image and the image description.
+```html
+<dialog class="mdlext-dialog">
+  <div class="mdlext-lightbox mdlext-js-lightbox mdl-card">
+    <div class="mdl-card__menu mdl-color-text--white mdl-typography--body-2-color-contrast">
+      <button data-action="close" class="mdl-button mdl-button--icon mdl-js-button mdl-js-ripple-effect" title="Close">
+        <i class="material-icons">close</i>
+      </button>
+    </div>
+    <figure class="mdl-card__media">
+      <img src="" alt>
+      <figcaption></figcaption>
+    </figure>
+  </div>
+</dialog>
+```
+
+
+&nbsp;6. Code a `<footer>` element with `class="mdl-card__actions"` to hold the image title and navigation buttons.
+```html
+<dialog class="mdlext-dialog">
+  <div class="mdlext-lightbox mdlext-js-lightbox mdl-card">
+    <div class="mdl-card__menu mdl-color-text--white mdl-typography--body-2-color-contrast">
+      <button data-action="close" class="mdl-button mdl-button--icon mdl-js-button mdl-js-ripple-effect" title="Close">
+        <i class="material-icons">close</i>
+      </button>
+    </div>
+    <figure class="mdl-card__media">
+      <img src="" alt>
+      <figcaption></figcaption>
+    </figure>
+    <footer class="mdl-card__actions">
+    </footer>    
+  </div>
+</dialog>
+```
+
+&nbsp;7. Code a `<div>` element with `class="mdl-card__supporting-text"` to hold the image title.
+```html
+<dialog class="mdlext-dialog">
+  <div class="mdlext-lightbox mdlext-js-lightbox mdl-card">
+    <div class="mdl-card__menu mdl-color-text--white mdl-typography--body-2-color-contrast">
+      <button data-action="close" class="mdl-button mdl-button--icon mdl-js-button mdl-js-ripple-effect" title="Close">
+        <i class="material-icons">close</i>
+      </button>
+    </div>
+    <figure class="mdl-card__media">
+      <img src="" alt>
+      <figcaption></figcaption>
+    </figure>
+    <footer class="mdl-card__actions">
+      <div class="mdl-card__supporting-text">
+      </div>
+    </footer>    
+  </div>
+</dialog>
+```
+
+&nbsp;8. Code a `<nav>` element to hold the navigation buttons.
+```html
+<dialog class="mdlext-dialog">
+  <div class="mdlext-lightbox mdlext-js-lightbox mdl-card">
+    <div class="mdl-card__menu mdl-color-text--white mdl-typography--body-2-color-contrast">
+      <button data-action="close" class="mdl-button mdl-button--icon mdl-js-button mdl-js-ripple-effect" title="Close">
+        <i class="material-icons">close</i>
+      </button>
+    </div>
+    <figure class="mdl-card__media">
+      <img src="" alt>
+      <figcaption></figcaption>
+    </figure>
+    <footer class="mdl-card__actions mdl-card--border">
+      <div class="mdl-card__supporting-text">
+      </div>
+      <nav>
+      </nav>      
+    </footer>    
+  </div>
+</dialog>
+```
+
+
+&nbsp;9. Add your navigation buttons with `class="mdl-button mdl-button--icon mdl-js-button mdl-js-ripple-effect"` inside the `<nav>` element.
+```html
+<dialog class="mdlext-dialog">
+  <div class="mdlext-lightbox mdlext-js-lightbox mdl-card">
+    <div class="mdl-card__menu mdl-color-text--white mdl-typography--body-2-color-contrast">
+      <button data-action="close" class="mdl-button mdl-button--icon mdl-js-button" title="Close">
+        <i class="material-icons">close</i>
+      </button>
+    </div>
+    <figure class="mdl-card__media">
+      <img src="" alt>
+      <figcaption></figcaption>
+    </figure>
+    <footer class="mdl-card__actions mdl-card--border">
+      <div class="mdl-card__supporting-text">
+      </div>
+      <nav>
+        <button data-action="first" class="mdl-button mdl-button--icon mdl-js-button" title="First">
+          <i class="material-icons">first_page</i>
+        </button>
+        <button data-action="prev" class="mdl-button mdl-button--icon mdl-js-button" title="Previous">
+          <i class="material-icons">chevron_left</i>
+        </button>
+        <button data-action="next" class="mdl-button mdl-button--icon mdl-js-button" title="Next">
+          <i class="material-icons">chevron_right</i>
+        </button>
+        <button data-action="last" class="mdl-button mdl-button--icon mdl-js-button" title="Last">
+          <i class="material-icons">last_page</i>
+        </button>
+      </nav>      
+    </footer>    
+  </div>
+</dialog>
+```
+Add as many buttons as you like. To identify the button that trigger an custom event, you should assign each button a unique data-action attribute value. 
+The data-action attribute will be emitted as a part of the custom event triggered when a button is clicked.
+
+&nbsp;10. Add an image and open the dialog.
+
+```javascript
+var dialog = document.querySelector('dialog');
+
+// A dialog element MUST be a child of document.body!!
+if(dialog.parentNode.tagName !== 'BODY') {
+  document.body.appendChild(dialog);
+}
+
+if (!('showModal' in dialog)) {
+  dialogPolyfill.registerDialog(dialog);
+}
+var lightbox = dialog.querySelector('.mdlext-lightbox');
+var img = lightbox.querySelector('img'); 
+var supportingText = lightbox.querySelector('.mdl-card__supporting-text');
+var imageDetails = lightbox.querySelector('figcaption'); 
+
+img.setAttribute("src", 'wiew-from-my-window.jpg');
+img.setAttribute("alt", 'View from my window');
+img.setAttribute("title", 'View from my window');
+img.setAttribute('data-img-url-prev', 'some-image.jpg');
+img.setAttribute('data-img-url-next', 'some-other-image.jpg');
+supportingText.innerHTML = 'View from my window';
+imageDetails.innerHTML = 'Photo taken from my window yesterday morning'; 
+
+if(!dialog.open) {
+  dialog.showModal();
+}
+```
+
+### Examples
+* See: [snippets/carousel.html](./snippets/lightbox.html)
+* TRy out [the live demo](http://leifoolsen.github.io/mdl-ext/demo/lightbox.html)
+
+## Keyboard interaction
+The lightbox interacts with the following keyboard keys.
+
+*   `Left arrow` - Emits a custom event with action='prev'
+*   `Right arrow` - Emits a custom event with action='next'
+*   `Up arrow` - behaves the same as left arrow.
+*   `Down arrow` - behaves the same as right arrow.
+*   `End` - Emits a custom event with action='last'
+*   `Home` - Emits a custom event with action='first'
+*   `Space` - Emits a custom event with action='select'
+*   `Esc` - Emits a custom event with action='cancel'
+
+## Mouse / Touch interaction
+*   `Drag/Swipe left` - Emits a custom event with action='next'
+*   `Drag/Swipe right` - Emits a custom event with action='prev'
+
+## Events
+The lightbox emits a custom **action** event when a button contained in the lightbox is clicked, an images is dragged or swiped, 
+or if one of the keys `Arrow Left`, `Arrow Up`, `Arrow Right`, `Arrow Down`, `Home`, `End`, `Space` or `Esc` is pressed. 
+The event has a detail object with the following content:
+```
+{
+  action, // one of: 'first', 'prev', 'next', 'last', 'select', 'close', 'cancel' - 
+          // or any value assigned to a button action attribute (empty string if no action assigned) 
+  source  // the button instance that caused the event, or the lightbox element if a key triggered the event
+}
+```
+
+## Configuration options
+
+The MDLEXT CSS classes apply various predefined visual and behavioral enhancements to the lightbox.
+The table below lists the available classes and their effects.
+
+| MDLEXT class | Effect | Remarks |
+|--------------|--------|---------|
+| `mdlext-lightbox` | Defines a container as an MDLEXT lightbox component | Required on `<div>` element |
+| `mdlext-js-lightbox` | Assigns basic MDL behavior to lightbox | Required on `<div>` element |
+| `mdlext-lightbox__slider` | Displays previous, current and next image when dragging | Element added by component |
+| `mdlext-lightbox__slider__slide` | Holds an image to display when dragging | Element added by component |
+
+<!--
+| `mdlext-lightbox--sticky-footer` | Positions footer at bottom of screen | Optional on `mdlext-lightbox` element |
+-->
+
+| Attribute | Effect | Remarks |
+|-----------|--------|---------|
+| `data-img-url-prev` | Displays previous image when dragging | URL to previous image in a collection |
+| `data-img-url-next` | Displays next image when dragging | URL to next imagein a collection |
+
+
+## How to use the component programmatically
+The [tests](../../test/lightbox/lightbox.spec.js) and the [snippets/lightbox.html](./snippets/lightbox.html) 
+code provides examples on how to use the component programmatically.
+
diff --git a/node_modules/mdl-ext/src/lightbox/snippets/lightbox.html b/node_modules/mdl-ext/src/lightbox/snippets/lightbox.html
new file mode 100644
index 0000000..095da06
--- /dev/null
+++ b/node_modules/mdl-ext/src/lightbox/snippets/lightbox.html
@@ -0,0 +1,553 @@
+<p>A lightbox displays an image filling the screen, and dimming out the rest of the web page. It acts as a modal dialog
+  using the <code>&lt;dialog&gt;</code> element as a container for the lightbox.
+  <strong>Click on one of the images to open the lightbox. Browse images in the lightbox using arrow keys, clicking on
+    one of the navigation buttons, or by dragging or swiping the image.</strong>
+</p>
+
+<!--
+  This example uses the data-details attribute to feed data to the lightbox.
+  Use any data structure that suits you to feed the lightbox.
+  The a element holds reference to lightbox image
+ -->
+<ul id="lightboard-for-lightbox" class="mdlext-lightboard mdlext-js-lightboard mdl-js-ripple-effect mdl-js-ripple-effect--ignore-events">
+  <li class="mdlext-lightboard__slide" data-details="[
+    { 'name': 'Title',            'value': 'Northern goshawk with prey' },
+    { 'name': 'Copyright &copy;', 'value': 'Leif Olsen' },
+    { 'name': 'Camera',           'value': 'Nikon D800E' },
+    { 'name': 'Lens',             'value': 'Nikkor 300mm/4 PF' },
+    { 'name': 'Converter',        'value': 'TC14-II' },
+    { 'name': 'Focal length',     'value': '420mm' },
+    { 'name': 'Aperture',         'value': 'f/7.1' },
+    { 'name': 'Shutter speed',    'value': '1/400s' }]" >
+    <a href="./images/_D802141.jpg" class="mdlext-lightboard__slide__frame">
+      <figure>
+        <img src="./images/_D802141.jpg" title="Northern goshawk with prey"/>
+        <figcaption>_D802141.jpg</figcaption>
+      </figure>
+    </a>
+  </li>
+  <li class="mdlext-lightboard__slide" data-details="[
+    { 'name': 'Title',            'value': 'Northern goshawk with prey' },
+    { 'name': 'Copyright &copy;', 'value': 'Leif Olsen' },
+    { 'name': 'Camera',           'value': 'Nikon D800E' },
+    { 'name': 'Lens',             'value': 'Nikkor 300mm/4 PF' },
+    { 'name': 'Converter',        'value': 'TC14-II' },
+    { 'name': 'Focal length',     'value': '420mm' },
+    { 'name': 'Aperture',         'value': 'f/7.1' },
+    { 'name': 'Shutter speed',    'value': '1/400s' }]" >
+    <a href="./images/_D802143-2.jpg" class="mdlext-lightboard__slide__frame">
+      <figure>
+        <img src="./images/_D802143.jpg" title="Northern goshawk with prey"/>
+        <figcaption>_D802143.jpg</figcaption>
+      </figure>
+    </a>
+  </li>
+  <li class="mdlext-lightboard__slide" data-details="[
+    { 'name': 'Title',            'value': 'Whooper swans in flight' },
+    { 'name': 'Copyright &copy;', 'value': 'Leif Olsen' } ]">
+    <a href="./images/_D802591.jpg" class="mdlext-lightboard__slide__frame">
+      <figure>
+        <img src="./images/_D802591.jpg" title="Whooper swans in flight"/>
+        <figcaption>_D802591.jpg</figcaption>
+      </figure>
+    </a>
+  </li>
+  <li class="mdlext-lightboard__slide" data-details="[
+    { 'name': 'Title',            'value': 'European green woodpecker' },
+    { 'name': 'Copyright &copy;', 'value': 'Leif Olsen' } ]">
+    <a href="./images/_D804370-3.jpg" class="mdlext-lightboard__slide__frame">
+      <figure>
+        <img src="./images/_D804370-3.jpg" title="European green woodpecker"/>
+        <figcaption>_D804370-3.jpg</figcaption>
+      </figure>
+    </a>
+  </li>
+  <li class="mdlext-lightboard__slide" data-details="[
+    { 'name': 'Title',            'value': 'The bridge' },
+    { 'name': 'Copyright &copy;', 'value': 'Leif Olsen' } ]" >
+    <a href="./images/_D808689.jpg" class="mdlext-lightboard__slide__frame">
+      <figure>
+        <img src="./images/_D808689.jpg" title="The bridge"/>
+        <figcaption>_D808689.jpg</figcaption>
+      </figure>
+    </a>
+  </li>
+  <li class="mdlext-lightboard__slide" data-details="[
+    { 'name': 'Title',            'value': 'Landscape in blue pastel' },
+    { 'name': 'Copyright &copy;', 'value': 'Leif Olsen' } ]" >
+    <a href="./images/_D802181.jpg" class="mdlext-lightboard__slide__frame">
+      <figure>
+        <img src="./images/_D802181.jpg" title="Landscape in blue pastel"/>
+        <figcaption>_D802181.jpg</figcaption>
+      </figure>
+    </a>
+  </li>
+  <li class="mdlext-lightboard__slide" data-details="[
+    { 'name': 'Title',            'value': 'Hiking the mountains of Dovre' },
+    { 'name': 'Copyright &copy;', 'value': 'Leif Olsen' } ]" >
+    <a href="./images/_D800912.jpg" class="mdlext-lightboard__slide__frame">
+      <figure>
+        <img src="./images/_D800912.jpg" title="Hiking the mountains of Dovre"/>
+        <figcaption>_D800912.jpg</figcaption>
+      </figure>
+    </a>
+  </li>
+  <li class="mdlext-lightboard__slide" data-details="[
+    { 'name': 'Title',            'value': 'The Polar Express, end of Line. Ny Aalesund, Spitsbergen' },
+    { 'name': 'Copyright &copy;', 'value': 'Leif Olsen' } ]" >
+    <a href="./images/_D809453-_D809457-3.jpg" class="mdlext-lightboard__slide__frame">
+      <figure>
+        <img src="./images/_D809453-_D809457-4.jpg" title="The Polar Express, end of Line" />
+        <figcaption>_D809453-_D809457-4.jpg</figcaption>
+      </figure>
+    </a>
+  </li>
+  <li class="mdlext-lightboard__slide" data-details="[
+    { 'name': 'Title',            'value': 'Still got the blues' },
+    { 'name': 'Description',      'value': 'PULSE, Kilden Consert Hall, Kristiansand' },
+    { 'name': 'Copyright &copy;', 'value': 'Leif Olsen' } ]" >
+    <a href="./images/_DSC8214-2.jpg" class="mdlext-lightboard__slide__frame">
+      <figure>
+        <img src="./images/_DSC8214.jpg" title="Still got the blues"/>
+        <figcaption>_DSC8214.jpg</figcaption>
+      </figure>
+    </a>
+  </li>
+  <li class="mdlext-lightboard__slide" data-details="[
+    { 'name': 'Title',            'value': 'Flowers' },
+    { 'name': 'Copyright &copy;', 'value': 'Leif Olsen' } ]" >
+    <a href="./images/_D800017.jpg" class="mdlext-lightboard__slide__frame">
+      <figure>
+        <img src="./images/_D800017.jpg" />
+        <figcaption>_D800017.jpg</figcaption>
+      </figure>
+    </a>
+  </li>
+  <li class="mdlext-lightboard__slide" data-details="[
+    { 'name': 'Title',            'value': 'Red-breasted merganser' },
+    { 'name': 'Copyright &copy;', 'value': 'Leif Olsen' } ]" >
+    <a href="./images/_D800023.jpg" class="mdlext-lightboard__slide__frame">
+      <figure>
+        <img src="./images/_D800023.jpg" />
+        <figcaption>_D800023.jpg</figcaption>
+      </figure>
+    </a>
+  </li>
+  <li class="mdlext-lightboard__slide" data-details="[
+    { 'name': 'Title',            'value': 'Musk oxes, Dovre, Norway' },
+    { 'name': 'Copyright &copy;', 'value': 'Leif Olsen' } ]" >
+    <a href="./images/_D800851.jpg" class="mdlext-lightboard__slide__frame">
+      <figure>
+        <img src="./images/_D800851.jpg" />
+        <figcaption>_D800851.jpg</figcaption>
+      </figure>
+    </a>
+  </li>
+  <li class="mdlext-lightboard__slide" data-details="[
+    { 'name': 'Title',            'value': 'Arctic Fox, Svalbard, Norway' },
+    { 'name': 'Copyright &copy;', 'value': 'Leif Olsen' } ]" >
+    <a href="./images/_D800166-2.jpg" class="mdlext-lightboard__slide__frame">
+      <figure>
+        <img src="./images/_D800166.jpg" />
+        <figcaption>_D800166.jpg</figcaption>
+      </figure>
+    </a>
+  </li>
+
+  <li class="mdlext-lightboard__slide" data-details="[
+    { 'name': 'Title',            'value': 'Fly fishing the arctic waters, Svalbard, Norway' },
+    { 'name': 'Copyright &copy;', 'value': 'Leif Olsen' } ]" >
+    <a href="#" class="mdlext-lightboard__slide__frame">
+      <figure>
+        <img src="./images/_D800951.jpg" />
+        <figcaption>_D800951.jpg</figcaption>
+      </figure>
+    </a>
+  </li>
+  <li class="mdlext-lightboard__slide" data-details="[
+    { 'name': 'Title',            'value': 'Lady of the snows (Pulsatilla vernalis), Dovre, Norway' },
+    { 'name': 'Copyright &copy;', 'value': 'Leif Olsen' },
+    { 'name': 'Camera',           'value': 'Nikon D800E' },
+    { 'name': 'Lens',             'value': 'Nikkor 400mm/2.8GEDVR' },
+    { 'name': 'Converter',        'value': 'TC1.4II' },
+    { 'name': 'Focal length',     'value': '550mm' },
+    { 'name': 'Aperture',         'value': 'f/8' },
+    { 'name': 'Shutter speed',    'value': '1/200s' }
+     ]" >
+    <a href="#" class="mdlext-lightboard__slide__frame">
+      <figure>
+        <img src="./images/_D801188.jpg" />
+        <figcaption>_D801188.jpg</figcaption>
+      </figure>
+    </a>
+  </li>
+  <li class="mdlext-lightboard__slide" data-details="[
+    { 'name': 'Title',            'value': 'PULSE, Kilden Consert Hall, Kristiansand' },
+    { 'name': 'Copyright &copy;', 'value': 'Leif Olsen' } ]" >
+    <a href="#" class="mdlext-lightboard__slide__frame">
+      <figure>
+        <img src="./images/_D801205-2.jpg" />
+        <figcaption>_D801205-2.jpg</figcaption>
+      </figure>
+    </a>
+  </li>
+  <li class="mdlext-lightboard__slide" data-details="[
+    { 'name': 'Title',            'value': 'PULSE, Kilden Consert Hall, Kristiansand' },
+    { 'name': 'Copyright &copy;', 'value': 'Leif Olsen' } ]" >
+    <a href="#" class="mdlext-lightboard__slide__frame">
+      <figure>
+        <img src="./images/_D801274.jpg" />
+        <figcaption>_D801274.jpg</figcaption>
+      </figure>
+    </a>
+  </li>
+  <li class="mdlext-lightboard__slide" data-details="[
+    { 'name': 'Title',            'value': 'Peregrine falcon, Norway' },
+    { 'name': 'Copyright &copy;', 'value': 'Leif Olsen' } ]" >
+    <a href="#" class="mdlext-lightboard__slide__frame">
+      <figure>
+        <img src="./images/_D801392.jpg" />
+        <figcaption>_D801392.jpg</figcaption>
+      </figure>
+    </a>
+  </li>
+  <li class="mdlext-lightboard__slide" data-details="[
+    { 'name': 'Title',            'value': 'Peregrine falcon, Norway' },
+    { 'name': 'Copyright &copy;', 'value': 'Leif Olsen' },
+    { 'name': 'Camera',           'value': 'Nikon D800E' },
+    { 'name': 'Lens',             'value': 'Nikkor 400mm/2.8GEDVR' },
+    { 'name': 'Focal length',     'value': '400mm' },
+    { 'name': 'Aperture',         'value': 'f/2.8' },
+    { 'name': 'Shutter speed',    'value': '1/800s' } ]" >
+    <a href="#" class="mdlext-lightboard__slide__frame">
+      <figure>
+        <img src="./images/_D801436.jpg" />
+        <figcaption>_D801392.jpg</figcaption>
+      </figure>
+    </a>
+  </li>
+  <li class="mdlext-lightboard__slide" data-details="[
+    { 'name': 'Title',            'value': 'Mr. Per E Knudsen' },
+    { 'name': 'Copyright &copy;', 'value': 'Leif Olsen' } ]" >
+    <a href="#" class="mdlext-lightboard__slide__frame">
+      <figure>
+        <img src="./images/_D801952-4.jpg" />
+        <figcaption>_D801952-4.jpg</figcaption>
+      </figure>
+    </a>
+  </li>
+  <li class="mdlext-lightboard__slide" data-details="[
+    { 'name': 'Title',            'value': 'Black Woodpecker' },
+    { 'name': 'Copyright &copy;', 'value': 'Leif Olsen' } ]" >
+    <a href="#" class="mdlext-lightboard__slide__frame">
+      <figure>
+        <img src="./images/_D807603.jpg" />
+        <figcaption>_D807603.jpg</figcaption>
+      </figure>
+    </a>
+  </li>
+  <li class="mdlext-lightboard__slide" data-details="[
+    { 'name': 'Title',            'value': 'Goshina' },
+    { 'name': 'Copyright &copy;', 'value': 'Leif Olsen' } ]" >
+    <a href="#" class="mdlext-lightboard__slide__frame">
+      <figure>
+        <img src="./images/_D807689.jpg" />
+        <figcaption>_D807689.jpg</figcaption>
+      </figure>
+    </a>
+  </li>
+  <li class="mdlext-lightboard__slide" data-details="[
+    { 'name': 'Title',            'value': 'Goshina' },
+    { 'name': 'Copyright &copy;', 'value': 'Leif Olsen' } ]" >
+    <a href="#" class="mdlext-lightboard__slide__frame">
+      <figure>
+        <img src="./images/_D807558.jpg" />
+        <figcaption>_D807689.jpg</figcaption>
+      </figure>
+    </a>
+  </li>
+  <li class="mdlext-lightboard__slide" data-details="[
+    { 'name': 'Title',            'value': 'Svalbard Rock ptarmigan' },
+    { 'name': 'Copyright &copy;', 'value': 'Leif Olsen' }]" >
+    <a href="./images/_D800464.jpg" class="mdlext-lightboard__slide__frame">
+      <figure>
+        <img src="./images/_D800464.jpg" />
+        <figcaption>_D800464.jpg</figcaption>
+      </figure>
+    </a>
+  </li>
+  <li class="mdlext-lightboard__slide" data-details="[
+    { 'name': 'Title',            'value': 'Nice, France' },
+    { 'name': 'Copyright &copy;', 'value': 'Leif Olsen' } ]" >
+    <a href="./images/_DSC7535-2.jpg" class="mdlext-lightboard__slide__frame">
+      <figure>
+        <img src="./images/_DSC7535.jpg" />
+        <figcaption>_DSC7535.jpg</figcaption>
+      </figure>
+    </a>
+  </li>
+  <li class="mdlext-lightboard__slide" data-details="[
+    { 'name': 'Title',            'value': 'Cheetah, Bloemfontain, South Africa' },
+    { 'name': 'Copyright &copy;', 'value': 'Leif Olsen' } ]" >
+    <a href="#" class="mdlext-lightboard__slide__frame">
+      <figure>
+        <img src="./images/_D802478.jpg" />
+        <figcaption>_D802478.jpg</figcaption>
+      </figure>
+    </a>
+  </li>
+  <li class="mdlext-lightboard__slide" data-details="[
+    { 'name': 'Title',            'value': 'Red Squirrel' },
+    { 'name': 'Copyright &copy;', 'value': 'Leif Olsen' } ]" >
+    <a href="#" class="mdlext-lightboard__slide__frame">
+      <figure>
+        <img src="./images/_D800698.jpg" />
+        <figcaption>_D800698.jpg</figcaption>
+      </figure>
+    </a>
+  </li>
+  <li class="mdlext-lightboard__slide" data-details="[
+    { 'name': 'Title',            'value': 'Milky Way, Bloemfontain, South Africa' },
+    { 'name': 'Copyright &copy;', 'value': 'Leif Olsen' },
+    { 'name': 'Camera',           'value': 'Nikon D800E' },
+    { 'name': 'Lens',             'value': 'Nikkor 20mm/1.8' },
+    { 'name': 'Focal length',     'value': '20mm' },
+    { 'name': 'Aperture',         'value': 'f/2.0' },
+    { 'name': 'Shutter speed',    'value': '15s' },
+    { 'name': 'ISO',              'value': '1600' }]" >
+    <a href="#" class="mdlext-lightboard__slide__frame">
+      <figure>
+        <img src="./images/_D803118.jpg" />
+        <figcaption>_D803118.jpg</figcaption>
+      </figure>
+    </a>
+  </li>
+  <li class="mdlext-lightboard__slide" data-details="[
+    { 'name': 'Title',            'value': 'Winter Light, Senja, Norway' },
+    { 'name': 'Copyright &copy;', 'value': 'Leif Olsen' } ]" >
+    <a href="#" class="mdlext-lightboard__slide__frame">
+      <figure>
+        <img src="./images/_D803521.jpg" />
+        <figcaption>_D803521.jpg</figcaption>
+      </figure>
+    </a>
+  </li>
+  <li class="mdlext-lightboard__slide" data-details="[
+    { 'name': 'Title',            'value': 'Selfie with Aurora B :)' },
+    { 'name': 'Copyright &copy;', 'value': 'Leif Olsen' } ]" >
+    <a href="#" class="mdlext-lightboard__slide__frame">
+      <figure>
+        <img src="./images/_D803465-3.jpg" />
+        <figcaption>_D803465-3.jpg</figcaption>
+      </figure>
+    </a>
+  </li>
+  <li class="mdlext-lightboard__slide" data-details="[
+    { 'name': 'Title',            'value': 'Lista Lighthouse, Norway' },
+    { 'name': 'Copyright &copy;', 'value': 'Leif Olsen' },
+    { 'name': 'Camera',           'value': 'Nikon D800E' },
+    { 'name': 'Lens',             'value': 'Nikkor 16mm/2.8D Fisheye' },
+    { 'name': 'Focal length',     'value': '16mm' },
+    { 'name': 'Aperture',         'value': 'f/8' },
+    { 'name': 'Shutter speed',    'value': '1/20s' },
+    { 'name': 'ISO',              'value': '100' } ]" >
+    <a href="#" class="mdlext-lightboard__slide__frame">
+      <figure>
+        <img src="./images/_D806374.jpg" />
+        <figcaption>_D803465-3.jpg</figcaption>
+      </figure>
+    </a>
+  </li>
+  <li class="mdlext-lightboard__slide" data-details="[
+    { 'name': 'Title',            'value': 'Osprey' },
+    { 'name': 'Copyright &copy;', 'value': 'Leif Olsen' },
+    { 'name': 'Camera',           'value': 'Nikon D800E' },
+    { 'name': 'Lens',             'value': 'Nikkor 400mm/2.8GEDVR' },
+    { 'name': 'Converter',        'value': 'TC1.4II' },
+    { 'name': 'Focal length',     'value': '550mm' },
+    { 'name': 'Aperture',         'value': 'f/5.6' },
+    { 'name': 'Shutter speed',    'value': '1/400s' } ]" >
+    <a href="#" class="mdlext-lightboard__slide__frame">
+      <figure>
+        <img src="./images/_D805345-12.jpg" />
+        <figcaption>_D805345-12.jpg</figcaption>
+      </figure>
+    </a>
+  </li>
+</ul>
+
+<p class="mdl-typography--caption" style="margin-top: 32px;">
+  All images appearing in this page are the exclusive property of Leif Olsen and are protected under the United States
+  and International Copyright laws. The images may not be reproduced or manipulated without the written permission of
+  Leif Olsen. Use of any image as the basis for another photographic concept or illustration (digital, artist rendering
+  or alike) is a violation of the United States and International Copyright laws. All images are copyrighted &copy; Leif Olsen, 2016.
+</p>
+
+
+<!-- A dialog element MUST be a child of document.body!! -->
+<dialog id="lightbox-dialog" class="mdlext-dialog">
+
+  <div id="lightbox" class="mdlext-lightbox mdlext-js-lightbox mdl-card mdl-shadow--4dp">
+    <div class="mdl-card__menu mdl-color-text--white mdl-typography--body-2-color-contrast">
+      <button data-action="close" class="mdl-button mdl-button--icon mdl-js-button" title="Close">
+        <i class="material-icons">close</i>
+      </button>
+    </div>
+    <figure class="mdl-card__title">
+      <img src="" draggable="true" alt>
+      <figcaption data-action="select">Details</figcaption>
+    </figure>
+    <footer data-action="select" class="mdl-card__actions mdl-card--border">
+      <div class="mdl-card__supporting-text">
+        Image title
+      </div>
+      <nav>
+        <button data-action="first" class="mdl-button mdl-button--icon mdl-js-button" title="First">
+          <i class="material-icons">first_page</i>
+        </button>
+        <button data-action="prev" class="mdl-button mdl-button--icon mdl-js-button" title="Previous">
+          <i class="material-icons">chevron_left</i>
+        </button>
+        <button data-action="next" class="mdl-button mdl-button--icon mdl-js-button" title="Next">
+          <i class="material-icons">chevron_right</i>
+        </button>
+        <button data-action="last" class="mdl-button mdl-button--icon mdl-js-button" title="Last">
+          <i class="material-icons">last_page</i>
+        </button>
+        <button data-action="select" class="mdl-button mdl-button--icon mdl-js-button" title="Details">
+          <i class="material-icons">info_outline</i>
+        </button>
+      </nav>
+    </footer>
+  </div>
+</dialog>
+
+<script>
+  window.addEventListener('load', function() {
+    var dialog = document.querySelector('#lightbox-dialog');
+
+    // A dialog element MUST be a child of document.body!!
+    // In a SPA you should choose a more robust strategy than the simple if provided here
+    if(dialog.parentNode.tagName !== 'BODY') {
+      document.body.appendChild(dialog);
+    }
+
+    if (!('showModal' in dialog)) {
+      dialogPolyfill.registerDialog(dialog);
+    }
+
+    var currentSlide = null;
+    var lightboard = document.querySelector('#lightboard-for-lightbox');
+    var slides = lightboard.querySelectorAll('.mdlext-lightboard__slide');
+
+    lightboard.addEventListener('select', function(e) {
+      currentSlide = e.detail.source;
+      for (var i = 0, n = slides.length; i < n; i++) {
+        if(currentSlide ===  slides[i]) {
+          break;
+        }
+      }
+      var prevSlide = slides[ i > 0   ? i-1 : n-1 ];
+      var nextSlide = slides[ i < n-1 ? i+1 : 0];
+      showImage(currentSlide, prevSlide, nextSlide);
+    });
+
+    var lightbox = dialog.querySelector('.mdlext-lightbox');
+
+    lightbox.addEventListener('action', function(e) {
+      if(e.detail.action === 'close') {
+        dialog.close();
+      }
+      else if(e.detail.action === 'select') {
+        var figcaption = lightbox.querySelector('figure figcaption');
+        if(figcaption.classList.contains('mdlext-lightbox__show-figcaption')) {
+          figcaption.classList.remove('mdlext-lightbox__show-figcaption');
+        }
+        else {
+          figcaption.classList.add('mdlext-lightbox__show-figcaption');
+        }
+      }
+      else {
+        var i = 0;
+        var n = slides.length
+
+        if(e.detail.action === 'first') {
+          currentSlide = slides[0];
+        }
+        else if(e.detail.action === 'prev' || e.detail.action === 'next') {
+          for (var j = 0; j < n; j++) {
+            if(currentSlide ===  slides[j]) {
+              if(e.detail.action === 'prev') {
+                i = j > 0 ? j-1 : n-1;
+                currentSlide = slides[i];
+              }
+              else if(e.detail.action === 'next') {
+                i = j < n-1 ? j+1 : 0;
+                currentSlide = slides[i];
+              }
+              break;
+            }
+          }
+        }
+        else if(e.detail.action === 'last') {
+          i = slides.length-1;
+          currentSlide = slides[i];
+        }
+        var prevSlide = slides[ i > 0   ? i-1 : n-1 ];
+        var nextSlide = slides[ i < n-1 ? i+1 : 0];
+        showImage(currentSlide, prevSlide, nextSlide);
+      }
+    });
+
+    function showImage(slide, prevSlide, nextSlide) {
+
+      var slideAnchor = slide.querySelector('a');
+      var slideImg = slide.querySelector('img');
+      var img = dialog.querySelector('img');
+      var supportingText = dialog.querySelector('.mdl-card__supporting-text');
+      var imageDetails = dialog.querySelector('figcaption');
+      var href = slideAnchor.getAttribute('href');
+      href = href && href.indexOf('#') === 0 ? slideImg.getAttribute('src') : href;
+      img.setAttribute('src', href);
+      img.setAttribute('alt', slideImg.getAttribute('title') || '');
+      img.setAttribute('title', slideImg.getAttribute('title') || '');
+      supportingText.innerHTML = slideImg.getAttribute('title') || '';
+
+      // Lazy coder :)
+      slideAnchor = prevSlide.querySelector('a');
+      slideImg = prevSlide.querySelector('img');
+      href = slideAnchor.getAttribute('href');
+      href = href && href.indexOf('#') === 0 ? slideImg.getAttribute('src') : href;
+      img.setAttribute('data-img-url-prev', href);
+
+      slideAnchor = nextSlide.querySelector('a');
+      slideImg = nextSlide.querySelector('img');
+      href = slideAnchor.getAttribute('href');
+      href = href && href.indexOf('#') === 0 ? slideImg.getAttribute('src') : href;
+      img.setAttribute('data-img-url-next', href);
+
+
+      var detailsHtml  = '';
+      var detailsArray = JSON.parse(slide.getAttribute('data-details').replace(/'/g, '"'));
+
+      if(detailsArray != null) {
+        detailsHtml = '<table><tbody>';
+        for (var i = 0, n = detailsArray.length; i < n; i++) {
+          detailsHtml += '<tr><th>' + detailsArray[i].name + '</th><td>' + detailsArray[i].value + '</td></tr>';
+
+          if(!supportingText.innerHTML && detailsArray[i].name.toLowerCase() === 'title') {
+            supportingText.innerHTML = detailsArray[i].value;
+          }
+        }
+        detailsHtml += '</tbody></table>';
+      }
+
+      imageDetails.innerHTML = '';
+      imageDetails.insertAdjacentHTML('afterbegin', detailsHtml);
+
+      if(!dialog.open) {
+        dialog.showModal();
+      }
+    }
+  });
+</script>
diff --git a/node_modules/mdl-ext/src/mdl-ext-build.scss b/node_modules/mdl-ext/src/mdl-ext-build.scss
new file mode 100644
index 0000000..beda184
--- /dev/null
+++ b/node_modules/mdl-ext/src/mdl-ext-build.scss
@@ -0,0 +1,8 @@
+@charset "UTF-8";
+
+// Material Design Lite
+@import '~material-design-lite/src/variables';
+@import '~material-design-lite/src/mixins';
+
+// mdl-ext
+@import 'mdl-ext';
diff --git a/node_modules/mdl-ext/src/mdl-ext-eqjs-build.scss b/node_modules/mdl-ext/src/mdl-ext-eqjs-build.scss
new file mode 100644
index 0000000..f321f90
--- /dev/null
+++ b/node_modules/mdl-ext/src/mdl-ext-eqjs-build.scss
@@ -0,0 +1,8 @@
+@charset "UTF-8";
+
+// Material Design Lite
+@import '~material-design-lite/src/variables';
+@import '~material-design-lite/src/mixins';
+
+// mdl-ext
+@import 'mdl-ext-eqjs';
diff --git a/node_modules/mdl-ext/src/mdl-ext-eqjs.scss b/node_modules/mdl-ext/src/mdl-ext-eqjs.scss
new file mode 100644
index 0000000..56af48f
--- /dev/null
+++ b/node_modules/mdl-ext/src/mdl-ext-eqjs.scss
@@ -0,0 +1,39 @@
+@charset "UTF-8";
+
+/**
+ * Element Queries are a new way of writing CSS styles so the rules apply to individual elements
+ * on the page, instead of to the whole page as one document like in regular CSS Media Queries.
+ * This SASS file includes the eq.js, https://github.com/Snugug/eq.js, prolyfill which is an easy to use
+ * drop-in solution to JavaScript powered element queries. It works well with SASS,
+ * and element queries work without requireing a server to run.
+ *
+ * Feel fre to write your own element query stylesheet using one of the other libraries, e.g:
+ *   [EQCSS]               - (https://github.com/eqcss/eqcss)
+ *   [CSS Element Queries] - (https://github.com/marcj/css-element-queries)
+ *   [BoomQueries]         - (https://github.com/BoomTownROI/boomqueries)
+ */
+
+// eq.js mixins
+@import '~eq.js/sass/eq';
+
+// Configuration and helpers
+@import 'variables';
+@import 'mixins';
+@import 'functions';
+
+// Components
+@import 'aria-expanded-toggle/aria-expanded-toggle';
+@import 'sticky-header/sticky-header';
+@import 'dialog/dialog';
+@import 'grid/grid-eqjs';
+@import 'lightboard/lightboard';
+@import 'lightboard/lightboard-eqjs';
+@import 'lightbox/lightbox';
+@import 'carousel/carousel';
+@import 'selectfield/selectfield';
+@import 'menu-button/menu-button';
+@import 'bordered-fields/bordered-fields';
+@import 'collapsible/collapsible';
+@import 'accordion/accordion';
+@import 'color-themes/light-color-theme';
+@import 'color-themes/dark-color-theme';
diff --git a/node_modules/mdl-ext/src/mdl-ext.scss b/node_modules/mdl-ext/src/mdl-ext.scss
new file mode 100644
index 0000000..0f57eb2
--- /dev/null
+++ b/node_modules/mdl-ext/src/mdl-ext.scss
@@ -0,0 +1,23 @@
+@charset "UTF-8";
+
+// Configuration and helpers
+@import 'variables';
+@import 'mixins';
+@import 'functions';
+
+// Components
+@import 'aria-expanded-toggle/aria-expanded-toggle';
+@import 'sticky-header/sticky-header';
+@import 'dialog/dialog';
+@import 'grid/grid-media-queries';
+@import 'lightboard/lightboard';
+@import 'lightboard/lightboard-media-queries';
+@import 'lightbox/lightbox';
+@import 'carousel/carousel';
+@import 'selectfield/selectfield';
+@import 'menu-button/menu-button';
+@import 'bordered-fields/bordered-fields';
+@import 'collapsible/collapsible';
+@import 'accordion/accordion';
+@import 'color-themes/light-color-theme';
+@import 'color-themes/dark-color-theme';
diff --git a/node_modules/mdl-ext/src/menu-button/_menu-button.scss b/node_modules/mdl-ext/src/menu-button/_menu-button.scss
new file mode 100644
index 0000000..9fd84d4
--- /dev/null
+++ b/node_modules/mdl-ext/src/menu-button/_menu-button.scss
@@ -0,0 +1,181 @@
+@charset "UTF-8";
+
+/**
+ * @license
+ * Copyright 2016 Leif Olsen. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * This code is built with Google Material Design Lite,
+ * which is Licensed under the Apache License, Version 2.0
+ */
+
+/* Moved to aria-expanded-toggle.scss
+
+.mdlext-aria-expanded-plus-minus {
+  @include mdlext-aria-expanded-toggle($font-family: inherit);
+}
+
+.mdlext-aria-expanded-more-less {
+  @include mdlext-aria-expanded-toggle($icon: 'expand_more', $icon-expanded: 'expand_less');
+}
+*/
+
+.mdlext-menu-button {
+  box-sizing: border-box;
+  @include typo-menu();
+  text-transform: none;
+  position: relative;
+  height: $button-height;
+  padding: 0 $button-padding;
+  display: flex;
+  align-items: center;
+  align-self: stretch;
+
+  > * {
+    margin: 0;
+    padding: 0 0 0 8px;
+  }
+
+  > *:first-child {
+    padding-left: 0;
+  }
+
+  > *:last-child:not(:only-child):not(.mdlext-menu__item__caption) {
+    margin-left: auto; // If more than one element, push last element to the right
+  }
+
+}
+
+.mdlext-menu-button__caption {
+  white-space: nowrap;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  line-height: 1.2;
+}
+
+.mdlext-menu,
+.mdlext-menu__item {
+  box-sizing: border-box;
+  margin: 0;
+  padding: 0;
+  list-style: none;
+  display: flex;
+}
+
+.mdlext-menu {
+  position: absolute; //fixed;
+  background: $default-dropdown-bg-color;
+  z-index: 1000;
+  min-width: 124px;
+  border-radius: 2px;
+  @include shadow-3dp();
+  display: inline-flex;
+  flex-direction: column;
+  padding: 0;
+  overflow: hidden;
+  overflow-y: auto;
+
+  &:focus {
+    outline-offset: -1px;
+    outline-width: 1px;
+  }
+
+  &[hidden] {
+    @include mdlext-visually-hidden;
+    pointer-events: none;
+  }
+
+  &__item {
+    @include typo-body-1();
+    color: $default-item-text-color;
+    background-color: $default-dropdown-bg-color;
+    position: relative;
+    padding: 0 16px 0 24px;
+    align-items: center;
+    align-self: stretch;
+    text-decoration: none;
+    cursor: pointer;
+    white-space: nowrap;
+    user-select: none;
+    min-height: 40px;
+    overflow: hidden;
+
+    &[aria-selected='true'] {
+      background-color: $default-item-active-bg-color;
+    }
+
+    // checkmark
+    &[aria-selected='true']::before {
+      content:'\2713';
+      position: absolute;
+      font-size: 1.4em;
+      left: 4px;
+      top: 50%;
+      transform: translateY(-50%);
+      pointer-events: none;
+    }
+
+    &:hover:not([disabled]) {
+      background-color: $default-item-hover-bg-color;
+    }
+
+    &:focus {
+      outline-offset: -2px;
+      outline-width: 1px;
+      outline-color: $default-item-outline-color;
+      background-color: $default-item-focus-bg-color;
+    }
+
+    &::-moz-focus-inner {
+      border: 0;
+    }
+
+    &[disabled] {
+      color: $disabled-item-text-color;
+      background-color: transparent;
+      cursor: auto;
+      pointer-events: none;
+
+      > * {
+        color: $disabled-item-text-color;
+      }
+    }
+
+    &__caption {
+      white-space: nowrap;
+      overflow: hidden;
+      text-overflow: ellipsis;
+    }
+
+    > * {
+      margin: 0;
+      padding: 0 0 0 8px;
+    }
+
+    > *:first-child {
+      padding-left: 0;
+    }
+
+    > *:last-child:not(:only-child):not(.mdlext-menu__item__caption) {
+      margin-left: auto; // If more than one element, push last element to the right
+    }
+
+  }
+  &__item-separator {
+    margin: 0;
+    padding: 0;
+    border-bottom: 1px solid $default-item-divider-color;
+  }
+
+}
diff --git a/node_modules/mdl-ext/src/menu-button/menu-button.js b/node_modules/mdl-ext/src/menu-button/menu-button.js
new file mode 100644
index 0000000..e7e37d8
--- /dev/null
+++ b/node_modules/mdl-ext/src/menu-button/menu-button.js
@@ -0,0 +1,758 @@
+/**
+ * @license
+ * Copyright 2016 Leif Olsen. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * This code is built with Google Material Design Lite,
+ * which is Licensed under the Apache License, Version 2.0
+ */
+
+
+/**
+ * A menu button is a button that opens a menu. It is often styled as a
+ * typical push button with a downward pointing arrow or triangle to hint
+ * that activating the button will display a menu.
+ */
+import { randomString } from '../utils/string-utils';
+import fullThrottle from '../utils/full-throttle';
+import {
+  VK_TAB,
+  VK_ENTER,
+  VK_ESC,
+  VK_SPACE,
+  VK_END,
+  VK_HOME,
+  VK_ARROW_LEFT,
+  VK_ARROW_UP,
+  VK_ARROW_RIGHT,
+  VK_ARROW_DOWN,
+  IS_UPGRADED,
+} from '../utils/constants';
+
+import { getScrollParents, tether } from '../utils/dom-utils';
+
+const JS_MENU_BUTTON = 'mdlext-js-menu-button';
+const MENU_BUTTON_MENU = 'mdlext-menu';
+const MENU_BUTTON_MENU_ITEM = 'mdlext-menu__item';
+const MENU_BUTTON_MENU_ITEM_SEPARATOR = 'mdlext-menu__item-separator';
+//const MDL_LAYOUT_CONTENT = 'mdl-layout__content';
+
+/**
+ * Creates the menu controlled by the menu button
+ * @param element
+ * @return {{element: Element, selected: Element, open: (function(*=)), removeListeners: (function()), downgrade: (function())}}
+ */
+
+const menuFactory = element => {
+
+  let ariaControls = null;
+  let parentNode = null;
+
+  const removeAllSelected = () => {
+    [...element.querySelectorAll(`.${MENU_BUTTON_MENU_ITEM}[aria-selected="true"]`)]
+      .forEach(selectedItem => selectedItem.removeAttribute('aria-selected'));
+  };
+
+  const setSelected = (item, force=false) => {
+    if(force || (item && !item.hasAttribute('aria-selected'))) {
+      removeAllSelected();
+      if(item) {
+        item.setAttribute('aria-selected', 'true');
+      }
+    }
+  };
+
+  const getSelected = () => {
+    return element.querySelector(`.${MENU_BUTTON_MENU_ITEM}[aria-selected="true"]`);
+  };
+
+  const isDisabled = item => item && item.hasAttribute('disabled');
+
+  const isSeparator = item => item && item.classList.contains(MENU_BUTTON_MENU_ITEM_SEPARATOR);
+
+  const focus = item => {
+    if(item) {
+      item = item.closest(`.${MENU_BUTTON_MENU_ITEM}`);
+    }
+    if(item) {
+      item.focus();
+    }
+  };
+
+  const nextItem = current => {
+    let n = current.nextElementSibling;
+    if(!n) {
+      n = element.firstElementChild;
+    }
+    if(!isDisabled(n) && !isSeparator(n)) {
+      focus(n);
+    }
+    else {
+      let i = element.children.length;
+      while(n && i-- > 0) {
+        if(isDisabled(n) || isSeparator(n)) {
+          n = n.nextElementSibling;
+          if(!n) {
+            n = element.firstElementChild;
+          }
+        }
+        else {
+          focus(n);
+          break;
+        }
+      }
+    }
+  };
+
+  const previousItem = current => {
+    let p = current.previousElementSibling;
+    if(!p) {
+      p = element.lastElementChild;
+    }
+    if(!isDisabled(p) && !isSeparator(p)) {
+      focus(p);
+    }
+    else {
+      let i = element.children.length;
+      while(p && i-- > 0) {
+        if(isDisabled(p) || isSeparator(p)) {
+          p = p.previousElementSibling;
+          if(!p) {
+            p = element.lastElementChild;
+          }
+        }
+        else {
+          focus(p);
+          break;
+        }
+      }
+    }
+  };
+
+  const firstItem = () => {
+    const item = element.firstElementChild;
+    if(isDisabled(item) || isSeparator(item) ) {
+      nextItem(item);
+    }
+    else {
+      focus(item);
+    }
+  };
+
+  const lastItem = () => {
+    const item = element.lastElementChild;
+    if(isDisabled(item) || isSeparator(item)) {
+      previousItem(item);
+    }
+    else {
+      focus(item);
+    }
+  };
+
+  const selectItem = item => {
+    if(item && !isDisabled(item) && !isSeparator(item)) {
+      setSelected(item);
+      close(true, item);
+    }
+  };
+
+  const keyDownHandler = event => {
+
+    const item = event.target.closest(`.${MENU_BUTTON_MENU_ITEM}`);
+
+    switch (event.keyCode) {
+      case VK_ARROW_UP:
+      case VK_ARROW_LEFT:
+        if(item) {
+          previousItem(item);
+        }
+        else {
+          firstItem();
+        }
+        break;
+
+      case VK_ARROW_DOWN:
+      case VK_ARROW_RIGHT:
+        if(item) {
+          nextItem(item);
+        }
+        else {
+          lastItem();
+        }
+        break;
+
+      case VK_HOME:
+        firstItem();
+        break;
+
+      case VK_END:
+        lastItem();
+        break;
+
+      case VK_SPACE:
+      case VK_ENTER:
+        selectItem(item);
+        break;
+
+      case VK_ESC:
+        close(true);
+        break;
+
+      case VK_TAB:
+        // We do not have a "natural" tab order from menu, so the best we can do is to set focus back to the button
+        close(true);
+        break;
+
+      default:
+        return;
+    }
+    event.preventDefault();
+  };
+
+
+  const blurHandler = event => {
+
+    // See: https://github.com/facebook/react/issues/2011
+    const t = event.relatedTarget ||
+      event.explicitOriginalTarget || // FF
+      document.activeElement;         // IE11
+
+    //console.log('***** blur, target, relatedTarget', event.target, t);
+
+    try {
+      if (t) {
+        if (t.closest(`.${MENU_BUTTON_MENU}`) !== element && shouldClose(t)) {
+          close();
+        }
+      }
+      else {
+        close();
+      }
+    }
+    catch(err) {
+      // FF throws error: "TypeError: n.closest is not a function" if related target is a text node
+      close();
+    }
+  };
+
+  const clickHandler = event => {
+    //console.log('***** click, target', event.target);
+
+    event.preventDefault();
+    const t = event.target;
+    if (t && t.closest(`.${MENU_BUTTON_MENU}`) === element) {
+      const item = t.closest(`.${MENU_BUTTON_MENU_ITEM}`);
+      if (item) {
+        selectItem(item);
+      }
+    }
+    else {
+      if (shouldClose(t)) {
+        close();
+      }
+    }
+  };
+
+  const touchStartHandler = event => {
+    //console.log('***** touchStart, target', event.target);
+
+    const t = event.target;
+    if(!(t && t.closest(`.${MENU_BUTTON_MENU}`) === element)) {
+      if (event.type === 'touchstart') {
+        event.preventDefault();
+      }
+      close();
+    }
+  };
+
+  const addListeners = () => {
+    element.addEventListener('keydown', keyDownHandler, false);
+    element.addEventListener('blur', blurHandler, true);
+    element.addEventListener('click', clickHandler, true);
+    document.documentElement.addEventListener('touchstart', touchStartHandler, true);
+  };
+
+  const removeListeners = () => {
+    element.removeEventListener('keydown', keyDownHandler, false);
+    element.removeEventListener('blur', blurHandler, true);
+    element.removeEventListener('click', clickHandler, true);
+    document.documentElement.removeEventListener('touchstart', touchStartHandler, true);
+  };
+
+  const open = (controlElement, position='first') => {
+
+    ariaControls = controlElement.closest(`.${JS_MENU_BUTTON}`);
+
+    element.style['min-width'] = `${Math.max(124, controlElement.getBoundingClientRect().width)}px`;
+    element.removeAttribute('hidden');
+    tether(controlElement, element);
+
+    let item;
+    switch (position.toLowerCase()) {
+      case 'first':
+        firstItem();
+        break;
+
+      case 'last':
+        lastItem();
+        break;
+
+      case 'selected':
+        item = getSelected();
+        if(item && !item.hasAttribute('disabled')) {
+          focus(item);
+        }
+        else {
+          firstItem();
+        }
+        break;
+    }
+
+    addListeners();
+  };
+
+
+  const shouldClose = target => {
+    //console.log('***** shouldClose');
+
+    let result = false;
+    const btn = (target && target.closest(`.${JS_MENU_BUTTON}`)) || null;
+    if(!btn) {
+      result = true;
+    }
+    else if(btn.getAttribute('aria-controls') === element.id) {
+      if(btn !== ariaControls) {
+        result = true;
+      }
+    }
+    else {
+      result = true;
+    }
+    return result;
+  };
+
+  const close = (forceFocus = false, item = null) => {
+    removeListeners();
+
+    element.dispatchEvent(
+      new CustomEvent('_closemenu', {
+        bubbles: true,
+        cancelable: true,
+        detail: { forceFocus: forceFocus, item: item }
+      })
+    );
+  };
+
+  const addWaiAria = () => {
+    if (!element.hasAttribute('id')) {
+      // Generate a random id
+      element.id = `menu-button-${randomString()}`;
+    }
+    element.setAttribute('tabindex', '-1');
+    element.setAttribute('role', 'menu');
+    element.setAttribute('hidden', '');
+
+    [...element.querySelectorAll(`.${MENU_BUTTON_MENU_ITEM}`)].forEach( menuitem => {
+      menuitem.setAttribute('tabindex', '-1');
+      menuitem.setAttribute('role', 'menuitem');
+    });
+
+    [...element.querySelectorAll(`.${MENU_BUTTON_MENU_ITEM_SEPARATOR}`)].forEach( menuitem => {
+      menuitem.setAttribute('role', 'separator');
+    });
+  };
+
+  const init = () => {
+    addWaiAria();
+    parentNode = element.parentNode;
+    element.classList.add('is-upgraded');
+  };
+
+  const downgrade = () => {
+    removeListeners();
+    if(element.parentNode !== parentNode) {
+      parentNode.appendChild(element);
+    }
+    element.classList.remove('is-upgraded');
+  };
+
+  init();
+
+  return {
+    /**
+     * Get the menu element
+     * @returns {Element} the menu element
+     */
+    get element() {
+      return element;
+    },
+
+    /**
+     * Set selected menu item
+     * @param item
+     */
+    set selected(item) {
+      setSelected(item, true);
+    },
+
+    /**
+     * Open menu
+     * @param {Element} controlElement the element where the menu should be aligned to
+     * @param {String} position menuElement item to receive focus after menu element is opened
+     */
+    open: (controlElement, position='first') => open(controlElement, position),
+
+    /**
+     * Remove event listeners.
+     */
+    removeListeners: () => removeListeners(),
+
+    /**
+     * Downgrade menu
+     */
+    downgrade: () => downgrade(),
+  };
+};
+
+
+/**
+ * The menubutton component
+ */
+
+class MenuButton {
+
+  constructor(element) {
+    this.element = element;
+    this.focusElement = undefined;
+    this.focusElementLastScrollPosition = undefined;
+    this.scrollElements = [];
+    this.menu = undefined;
+    this.selectedItem = null;
+    this.init();
+  }
+
+  keyDownHandler = event => {
+    if(!this.isDisabled()) {
+      switch (event.keyCode) {
+        case VK_ARROW_UP:
+          this.openMenu('last');
+          break;
+
+        case VK_ARROW_DOWN:
+          this.openMenu();
+          break;
+
+        case VK_SPACE:
+        case VK_ENTER:
+          this.openMenu('selected');
+          break;
+
+        case VK_ESC:
+          this.closeMenu();
+          break;
+
+        case VK_TAB:
+          this.closeMenu();
+          return;
+
+        default:
+          return;
+      }
+    }
+    //event.stopPropagation();
+    event.preventDefault();
+  };
+
+  clickHandler = () => {
+    if(!this.isDisabled()) {
+      if(this.element.getAttribute('aria-expanded').toLowerCase() === 'true') {
+        this.closeMenu(true);
+      }
+      else {
+        this.openMenu('selected');
+      }
+    }
+  };
+
+  /**
+   * Re-position menu if content is scrolled, window is resized or orientation change
+   * @see https://javascriptweblog.wordpress.com/2015/11/02/of-classes-and-arrow-functions-a-cautionary-tale/
+   */
+  recalcMenuPosition = fullThrottle( () => {
+    const c = this.focusElement.getBoundingClientRect();
+    const dx = this.focusElementLastScrollPosition.left - c.left;
+    const dy = this.focusElementLastScrollPosition.top - c.top;
+    const left = (parseFloat(this.menu.element.style.left) || 0) - dx;
+    const top = (parseFloat(this.menu.element.style.top) || 0) - dy;
+
+    this.menu.element.style.left = `${left}px`;
+    this.menu.element.style.top = `${top}px`;
+    this.focusElementLastScrollPosition = c;
+  });
+
+
+  positionChangeHandler = () => {
+    this.recalcMenuPosition(this);
+  };
+
+  closeMenuHandler = event => {
+    if(event && event.detail) {
+      if(event.detail.item && event.detail.item !== this.selectedItem) {
+        this.selectedItem = event.detail.item;
+        this.dispatchMenuSelect();
+      }
+      this.closeMenu(event.detail.forceFocus);
+    }
+  };
+
+  dispatchMenuSelect() {
+    this.element.dispatchEvent(
+      new CustomEvent('menuselect', {
+        bubbles: true,
+        cancelable: true,
+        detail: { source: this.selectedItem }
+      })
+    );
+  }
+
+  isDisabled() {
+    return this.element.hasAttribute('disabled');
+  }
+
+  removeListeners() {
+    this.element.removeEventListener('keydown', this.keyDownHandler);
+    this.element.removeEventListener('click', this.clickHandler);
+  }
+
+  openMenu(position='first') {
+
+    if(!this.isDisabled() && this.menu) {
+
+      // Close the menu if button position change
+      this.scrollElements = getScrollParents(this.element);
+      this.scrollElements.forEach(el => el.addEventListener('scroll', this.positionChangeHandler));
+
+      window.addEventListener('resize', this.positionChangeHandler);
+      window.addEventListener('orientationchange', this.positionChangeHandler);
+      this.menu.element.addEventListener('_closemenu', this.closeMenuHandler);
+
+      this.menu.selected = this.selectedItem;
+      this.menu.open(this.focusElement, position);
+      this.element.setAttribute('aria-expanded', 'true');
+
+      this.focusElementLastScrollPosition = this.focusElement.getBoundingClientRect();
+    }
+  }
+
+  closeMenu(forceFocus = false) {
+    if(this.menu) {
+      this.menu.removeListeners();
+      this.scrollElements.forEach(el => el.removeEventListener('scroll', this.positionChangeHandler));
+      window.removeEventListener('resize', this.positionChangeHandler);
+      window.removeEventListener('orientationchange', this.positionChangeHandler);
+      this.menu.element.removeEventListener('_closemenu', this.closeMenuHandler);
+
+      if (forceFocus) {
+        this.focus();
+      }
+      this.element.setAttribute('aria-expanded', 'false');
+      this.menu.element.setAttribute('hidden', '');
+    }
+  }
+
+  focus() {
+    if(!this.isDisabled()) {
+      this.focusElement.focus();
+    }
+  }
+
+  init() {
+    const addListeners = () => {
+      this.element.addEventListener('keydown', this.keyDownHandler);
+      this.element.addEventListener('click', this.clickHandler);
+    };
+
+    const addWaiAria = () => {
+      this.element.setAttribute('role', 'button');
+      this.element.setAttribute('aria-expanded', 'false');
+      this.element.setAttribute('aria-haspopup', 'true');
+    };
+
+    const addFocusElement = () => {
+      this.focusElement = this.element.querySelector('input[type="text"]');
+      if(!this.focusElement) {
+        this.focusElement = this.element;
+
+        if(!(this.focusElement.tagName.toLowerCase() === 'button' || this.focusElement.tagName.toLowerCase() === 'input')) {
+          if (!this.focusElement.hasAttribute('tabindex')) {
+            this.focusElement.setAttribute('tabindex', '0');
+          }
+        }
+      }
+    };
+
+    const moveElementToDocumentBody = (element) => {
+      // To position an element on top of all other z-indexed elements, the element should be moved to document.body
+      //       See: https://philipwalton.com/articles/what-no-one-told-you-about-z-index/
+
+      if(element.parentNode !== document.body) {
+        return document.body.appendChild(element);
+      }
+      return element;
+    };
+
+    const findMenuElement = () => {
+      let menuElement;
+      const menuElementId = this.element.getAttribute('aria-controls');
+      if(menuElementId !== null) {
+        menuElement = document.querySelector(`#${menuElementId }`);
+      }
+      else {
+        menuElement = this.element.parentNode.querySelector(`.${MENU_BUTTON_MENU}`);
+      }
+      return menuElement;
+    };
+
+    const addMenu = () => {
+      const menuElement = findMenuElement();
+      if(menuElement) {
+        if(menuElement.componentInstance) {
+          this.menu = menuElement.componentInstance;
+        }
+        else {
+          this.menu = menuFactory(menuElement);
+          menuElement.componentInstance = this.menu;
+          moveElementToDocumentBody(menuElement);
+        }
+        this.element.setAttribute('aria-controls', this.menu.element.id);
+      }
+    };
+
+    addFocusElement();
+    addWaiAria();
+    addMenu();
+    this.removeListeners();
+    addListeners();
+  }
+
+  downgrade() {
+    if(this.menu) {
+      // Do not downgrade menu if there are other buttons sharing this menu
+      const related = [...document.querySelectorAll(`.${JS_MENU_BUTTON}[aria-controls="${this.element.getAttribute('aria-controls')}"]`)];
+      if(related.filter( c => c !== this.element && c.getAttribute('data-upgraded').indexOf('MaterialExtMenuButton') >= 0).length === 0) {
+        this.menu.downgrade();
+      }
+    }
+    this.removeListeners();
+  }
+
+}
+
+(function() {
+  'use strict';
+
+  /**
+   * https://github.com/google/material-design-lite/issues/4205
+   * @constructor
+   * @param {Element} element The element that will be upgraded.
+   */
+  const MaterialExtMenuButton = function MaterialExtMenuButton(element) {
+    this.element_ = element;
+    this.menuButton_ = null;
+
+    // Initialize instance.
+    this.init();
+  };
+  window['MaterialExtMenuButton'] = MaterialExtMenuButton;
+
+
+  // Public methods.
+
+  /**
+   * Get the menu element controlled by this button, null if no menu is controlled by this button
+   * @public
+   */
+  MaterialExtMenuButton.prototype.getMenuElement = function() {
+    return this.menuButton_.menu ? this.menuButton_.menu.element : null;
+  };
+  MaterialExtMenuButton.prototype['getMenuElement'] = MaterialExtMenuButton.prototype.getMenuElement;
+
+  /**
+   * Open menu
+   * @public
+   * @param {String} position one of "first", "last" or "selected"
+   */
+  MaterialExtMenuButton.prototype.openMenu = function(position) {
+    this.menuButton_.openMenu(position);
+  };
+  MaterialExtMenuButton.prototype['openMenu'] = MaterialExtMenuButton.prototype.openMenu;
+
+  /**
+   * Close menu
+   * @public
+   */
+  MaterialExtMenuButton.prototype.closeMenu = function() {
+    this.menuButton_.closeMenu(true);
+  };
+  MaterialExtMenuButton.prototype['closeMenu'] = MaterialExtMenuButton.prototype.closeMenu;
+
+  /**
+   * Get selected menu item
+   * @public
+   * @returns {Element} The selected menu item or null if no item selected
+   */
+  MaterialExtMenuButton.prototype.getSelectedMenuItem = function() {
+    return this.menuButton_.selectedItem;
+  };
+  MaterialExtMenuButton.prototype['getSelectedMenuItem'] = MaterialExtMenuButton.prototype.getSelectedMenuItem;
+
+
+  /**
+   * Set (default) selected menu item
+   * @param {Element} item
+   */
+  MaterialExtMenuButton.prototype.setSelectedMenuItem = function(item) {
+    this.menuButton_.selectedItem = item;
+  };
+  MaterialExtMenuButton.prototype['setSelectedMenuItem'] = MaterialExtMenuButton.prototype.setSelectedMenuItem;
+
+  /**
+   * Initialize component
+   */
+  MaterialExtMenuButton.prototype.init = function() {
+    if (this.element_) {
+      this.menuButton_ = new MenuButton(this.element_);
+      this.element_.addEventListener('mdl-componentdowngraded', this.mdlDowngrade_.bind(this));
+      this.element_.classList.add(IS_UPGRADED);
+    }
+  };
+
+  /**
+   * Downgrade component
+   * E.g remove listeners and clean up resources
+   */
+  MaterialExtMenuButton.prototype.mdlDowngrade_ = function() {
+    this.menuButton_.downgrade();
+  };
+
+  // The component registers itself. It can assume componentHandler is available
+  // in the global scope.
+  /* eslint no-undef: 0 */
+  componentHandler.register({
+    constructor: MaterialExtMenuButton,
+    classAsString: 'MaterialExtMenuButton',
+    cssClass: JS_MENU_BUTTON,
+    widget: true
+  });
+})();
diff --git a/node_modules/mdl-ext/src/menu-button/readme.md b/node_modules/mdl-ext/src/menu-button/readme.md
new file mode 100644
index 0000000..ab3a219
--- /dev/null
+++ b/node_modules/mdl-ext/src/menu-button/readme.md
@@ -0,0 +1,472 @@
+# Menu Button
+![Menu button](../../etc/menu-button.png)&nbsp;&nbsp;&nbsp;&nbsp; ![Menu button](../../etc/menu-button-2.png)
+
+A WAI-ARIA friendly menu button component/widget with roles, attributes and behavior in accordance with the specification 
+given in WAI-ARIA Authoring Practices, [section 2.20](https://www.w3.org/TR/wai-aria-practices/#button).
+
+## Introduction
+A menu button is a button that opens a menu. It is often styled as a typical push button with a 
+downward pointing arrow or triangle to hint that activating the button will display a menu. 
+
+A menu is a widget that offers a list of choices to the user, such as a set of actions or functions. A menu is (usually) 
+opened, or made visible, by activating a menu button. When a user activates a choice in a menu, the menu (usually) closes.
+
+In this release a `<button>`, an `<input type="text">` or a `<div>` (mdl-textfield) can have `role="button"`, and act as 
+the control for a menu. 
+
+## To include a MDLEXT **menu button** component:
+
+&nbsp;1. Code a `<button>` element; this is the clickable toggle that will show and hide the menu. Include an `aria-controls` 
+attribute whose value will match the id attribute of the unordered list coded in the next step. Inside the button, 
+code a `<span>` element to hold the button caption text and a `<i>` element to contain a state icon.
+
+```html
+<button aria-controls="menu1">
+  <span></span>
+  <i></i>
+</button>
+```
+
+&nbsp;2. Code a `<ul>` unordered list element; this is the container that holds the menu choices. Include an id attribute 
+whose value will match the `aria-controls` attribute of the button element.
+
+```html
+<ul id="menu1">
+</ul>
+```
+
+&nbsp;3. Inside the unordered list, code one `<li>` element for each choice. Add a text caption as appropriate.
+
+```html
+<ul id="menu1">
+  <li>Small</li>
+  <li>Medium</li>
+  <li>Large</li>
+</ul>
+```
+
+&nbsp;4. Add one or more MDL classes, separated by spaces, to the button, span and i elements using the class attribute.
+
+```html
+<button class="mdl-button mdl-js-button" aria-controls="menu1">
+  <span>Select a value</span>
+  <i class="material-icons">more_vert</i>
+</button>
+```
+
+&nbsp;5. Add the `mdlext-js-menu-button` class to define the element as a menu button component.
+
+```html
+<button class="mdl-button mdl-js-button mdlext-js-menu-button" aria-controls="menu1">
+  <span>Select a value</span>
+  <i class="material-icons">more_vert</i>
+</button>
+```
+
+&nbsp;6. Add the `mdlext-menu` class to the unordered list and the `mdlext-menu__item` class to the list items. 
+
+```html
+<ul id="menu1" class="mdlext-menu">
+  <li class="mdlext-menu__item">Small</li>
+  <li class="mdlext-menu__item">Medium</li>
+  <li class="mdlext-menu__item">Large</li>
+</ul>
+```
+
+The menu button component is ready for use.
+
+>**Note:** After page load, the component will add all required Aria roles and attributes.
+
+```html
+<button class="mdl-button mdl-js-button mdlext-js-menu-button" 
+  role="button" aria-expanded="false" aria-haspopup="true" aria-controls="menu1">
+  <span>Select a value</span>
+  <i class="material-icons">more_vert</i>
+</button>
+<ul  id="menu1" class="mdlext-menu" role="menu" tabindex="-1" hidden>
+  <li class="mdlext-menu__item" role="menuitem" tabindex="-1">Small</li>
+  <li class="mdlext-menu__item" role="menuitem" tabindex="-1">Medium</li>
+  <li class="mdlext-menu__item" role="menuitem" tabindex="-1">Large</li>
+</ul>
+```
+
+
+### Examples
+
+**A menu button with three options.**
+
+```html
+<button class="mdl-button mdl-js-button mdlext-js-menu-button" aria-controls="menu1">
+  <span>Select a value</span>
+  <i class="material-icons">more_vert</i>
+</button>
+<ul id="menu1" class="mdlext-menu">
+  <li class="mdlext-menu__item">Small</li>
+  <li class="mdlext-menu__item">Medium</li>
+  <li class="mdlext-menu__item">Large</li>
+</ul>
+```
+
+> **Note:** If the button and the menu has a common ancestor element, the `aria-controls` attribute of the button and 
+the `id` attribute of the menu may be skipped.
+
+```html
+<div role="presentation">
+  <button class="mdl-button mdl-js-button mdlext-js-menu-button">
+    <span>Select a value</span>
+    <i class="material-icons">more_vert</i>
+  </button>
+  <ul class="mdlext-menu">
+    <li class="mdlext-menu__item">Small</li>
+    <li class="mdlext-menu__item">Medium</li>
+    <li class="mdlext-menu__item">Large</li>
+  </ul>
+</div>
+```
+
+With this markup the component will generate a random `id` attribute for the menu and associate it with the `aria-controls` 
+of the button.
+
+
+**A menu button with a select listener. Uses a data-value attribute to pass the actual value.**
+
+```html
+<div>
+  <button id="my-button" class="mdl-button mdl-js-button mdl-button--icon mdl-button--primary mdlext-js-menu-button"
+    onmenuselect="document.querySelector('#selection').innerHTML = 'Selected value: ' + event.detail.source.getAttribute('data-value');">
+    <span>Select</span>
+    <i class="mdlext-aria-expanded-more-less"></i>
+  </button>
+  <ul class="mdlext-menu" hidden >
+    <li class="mdlext-menu__item" data-value="10">Ten</li>
+    <li class="mdlext-menu__item" data-value="25">Twentyfive</li>
+    <li class="mdlext-menu__item" data-value="50">Fifty</li>
+  </ul>
+</div>
+```
+```javascript
+document.querySelector('#my-button').addEventListener('menuselect', function(event) {
+  this.querySelector('span').innerHTML = 'Selected value: ' + 
+    event.detail.source.getAttribute('data-value')
+});
+```
+
+
+**A menu button decorated with icons**
+
+```html
+<style>
+.material-icons.md-18 {
+   font-size: 18px;
+}
+</style>
+
+<button class="mdl-button mdl-button--raised mdl-js-ripple-effect mdl-js-button mdlext-js-menu-button"
+  aria-controls="demo-menu">
+  <i class="material-icons">gesture</i>
+  <span class="mdlext-menu-button__caption">Select</span>
+  <i class="material-icons mdlext-aria-expanded-more-less"></i>
+</button>
+
+<ul id="demo-menu" class="mdlext-menu" hidden>
+  <li class="mdlext-menu__item">
+    <i class="material-icons md-18">info</i>
+    <span class="mdlext-menu__item__caption">Menu item #1</span>
+  </li>
+  <li class="mdlext-menu__item">
+    <i class="material-icons md-18">help_outline</i>
+    <span class="mdlext-menu__item__caption">Menu item #2. A long text to check ellipsis overflow 0123456789</span>
+    <i class="material-icons md-18">radio</i>
+  </li>
+  <li class="mdlext-menu__item-separator"></li>
+  <li class="mdlext-menu__item" disabled>
+    <span class="mdlext-menu__item__caption">Menu item #3, disabled</span>
+    <i class="material-icons md-18">accessibility</i>
+  </li>
+  <li class="mdlext-menu__item-separator"></li>
+  <li class="mdlext-menu__item">
+    <span class="mdlext-menu__item__caption">Menu item #IV</span>
+    <i class="material-icons md-18">build</i>
+  </li>
+  <li class="mdlext-menu__item">
+    <span class="mdlext-menu__item__caption">Menu item #V</span>
+    <i class="material-icons md-18">build</i>
+  </li>
+  <li class="mdlext-menu__item-separator"></li>
+  <li class="mdlext-menu__item">
+    <span class="mdlext-menu__item__caption">Menu item #VI</span>
+    <i class="material-icons md-18">build</i>
+  </li>
+  <li class="mdlext-menu__item">
+    <span class="mdlext-menu__item__caption">Menu item #VII</span>
+    <i class="material-icons md-18">build</i>
+  </li>
+  <li class="mdlext-menu__item">
+    Menu item #n
+  </li>
+</ul>
+```
+
+**A mdl-textfield component can be used as a menu button.**
+
+```html
+<style>
+  .mdl-textfield.mdlext-js-menu-button .mdl-textfield__input {
+    padding-right: 40px;
+  }
+  .mdl-textfield__icon {
+    width: 32px;
+    text-align: left;
+    position: absolute;
+    right: 0;
+    top: 50%;
+    transform: translateY(-50%);
+  }
+  .mdl-textfield.is-disabled .mdl-textfield__icon {
+    color: rgba(0, 0, 0, 0.26) !important;
+  }
+  .mdl-textfield.is-invalid .mdl-textfield__icon {
+    color: #de3226 !important;
+  }
+</style>
+
+<div role="presentation">
+  <div id="my-textfield" class="mdl-textfield mdl-js-textfield mdlext-js-menu-button">
+    <input class="mdl-textfield__input" type="text" readonly>
+    <label class="mdl-textfield__label">Sign in with ...</label>
+    <i class="material-icons mdl-textfield__icon mdlext-aria-expanded-more-less"></i>
+  </div>
+  <ul class="mdlext-menu" hidden >
+    <li class="mdlext-menu__item" data-key="S">Small</li>
+    <li class="mdlext-menu__item" data-key="M">Medium</li>
+    <li class="mdlext-menu__item" data-key="L">Large</li>
+  </ul>
+</div>
+```
+```javascript
+document.querySelector('#my-textfield').addEventListener('menuselect', function(event) {
+  this.MaterialTextfield.change(event.detail.source.getAttribute('data-key') 
+           + ': ' + event.detail.source.querySelector('span').innerHTML);
+});
+```
+
+**Create your own state icon with SASS.**
+The [_mixins.scss](../_mixins.scss) has a mixin which can be used to create custom state icons.  
+
+```sass
+@charset "UTF-8";
+.my-aria-expanded-state {
+  @include mdlext-aria-expanded-toggle($icon: 'arrow_downward', $icon-expanded: 'arrow_upward');
+}
+```
+
+**Use a custom styled `div` as a menu button.**
+
+```html
+<div role="presentation">
+  <div id="my-div" class="mdlext-menu-button mdlext-js-menu-button" 
+       style="width:300px; height:44px; max-width:100%; border:1px solid green">
+       
+    <span class="mdlext-menu-button__caption">Select a size ...</span>
+    <i class="material-icons my-aria-expanded-state"></i>
+  </div>
+  <ul class="mdlext-menu" hidden >
+    <li class="mdlext-menu__item" data-key="S">Small</li>
+    <li class="mdlext-menu__item" data-key="M">Medium</li>
+    <li class="mdlext-menu__item" data-key="L">Large</li>
+  </ul>
+</div>
+```
+```javascript
+document.querySelector('#my-div').addEventListener('menuselect', function(event) {
+  this.querySelector('span').innerHTML = 
+     event.detail.source.getAttribute('data-key') + ': ' + 
+     event.detail.source.querySelector('span').innerHTML);
+});
+```
+
+**Many buttons can share one menu.**
+
+```html
+<button class="mdl-button mdl-js-button mdlext-js-menu-button" aria-controls="shared-menu">
+  <span class="mdlext-menu-button__caption">A button</span>
+</button>
+
+<div class="mdl-textfield mdl-js-textfield mdlext-js-menu-button" aria-controls="shared-menu">
+  <input class="mdl-textfield__input" type="text" readonly>
+  <label class="mdl-textfield__label">A MDL textfield</label>
+</div>
+
+<ul id="shared-menu" class="mdlext-menu" hidden>
+  <li class="mdlext-menu__item" role="menuitem">Menu item #1</li>
+  <li class="mdlext-menu__item" role="menuitem">Menu item #2</li>
+  <li class="mdlext-menu__item" role="menuitem">Menu item #n</li>
+</ul>
+```
+
+
+### More examples
+* The [snippets/menu-button.html](./snippets/menu-button.html) and the [tests](../../test/menu-button/menu-button.spec.js) provides more detailed examples.
+* Try out the [live demo](http://leifoolsen.github.io/mdl-ext/demo/menu-button.html)
+
+
+## Characteristics
+
+### Keyboard interaction, Menu Button 
+* With focus on the button:
+    * <kbd>Space</kbd> or <kbd>Enter</kbd>: opens the menu, sets `aria-expanded="true"`, and place focus on the previously selected menu item - or on the first menu item if no selected menu item.
+    * <kbd>Down Arrow</kbd>: opens the menu, sets `aria-expanded="true"`, and moves focus to the first menu item.
+    * <kbd>Up Arrow</kbd>: opens the menu, sets `aria-expanded="true"`, and moves focus to the last menu item.
+
+### Mouse interaction, Menu Button 
+* With focus on the button:
+    * <kbd>Click</kbd>: opens the menu, sets `aria-expanded="true"`, and place focus on the previously selected menu item - or on the first menu item if no selected menu item.
+    * <kbd>Click</kbd>: a second click closes the menu, sets `aria-expanded="false"` and place focus on button.
+    
+### Keyboard interaction, Menu
+* With focus on the menu:
+    * <kbd>Space</kbd> or <kbd>Enter</kbd>: sets `aria-selected="true"` on active menu item, sets `aria-expanded="true"` on menu button, closes menu and moves focus back to menu button. The button emits a custom `select` event with a referfence to the selected menu element.
+    * <kbd>Home</kbd>: move focus to first menu item.
+    * <kbd>End</kbd>: move focus to last menu item.
+    * <kbd>Up Arrow</kbd> or <kbd>Left Arrow</kbd>: move focus to previous menu item.
+    * <kbd>Down Arrow</kbd> or <kbd>Right Arrow</kbd>: Move focus to next menu item.
+    * <kbd>Esc</kbd>: Closes the menu, sets `aria-expanded="true"` on menu button, and move focus back to menu button.
+
+>The keyboard behavior after the menu is open are described in more detail in WAI-ARIA Authoring Practices, [2.19 Menu or Menu bar](https://www.w3.org/TR/wai-aria-practices/#menu).
+
+### Mouse interaction, Menu
+* With focus on the menu:
+    * <kbd>Click</kbd>: sets `aria-selected="true"` on active menu item, sets `aria-expanded="true"` on menu button, closes menu and moves focus back to menu button. The button emits a custom `select` event with a referfence to the selected menu element. 
+
+## WAI-ARIA Roles, States, and Properties
+The menu button has the following roles, states and properties set by the menu button component.
+
+### Menu Button
+* `role="button"`: the element that opens the menu has role [button](http://www.w3.org/TR/wai-aria-1.1/#button).
+* `aria-haspopup`: the element with role `button` has [aria-haspopup](http://www.w3.org/TR/wai-aria-1.1/#aria-haspopup) set to `true`.
+* `aria-controls`: identfies the content on the page (e.g. using IDREFs) that this menu button controls.
+* `aria-expanded`: the element with role `button` has [aria-expanded](https://www.w3.org/TR/wai-aria-1.1/#aria-expanded) set to `true` if the corresponding menu is open, oterwise false.
+* `aria-expanded`: when a menu item is disabled, `aria-disabled` is set to `true`.
+* `disabled"`: indicates that a button is disabled, otherwise not present.
+
+### Menu, WAI-ARIA Roles
+* `role="menu"`: identifies the element as a menu widget.
+* `hidden`: the menu has attrubute hidden if the controlling buttoun has `aria-expanded="false"`, otherwise the attribute is not present.
+* `role="menuitem"`: identifies an element as a menu item widget.
+* `role="menuitemcheckbox"`: (not yet implemented).
+* `role="menuitemradion"`: (not yet implemented).
+* `aria-selected`: the selected menu item has `aria-selected="true"`, otherwise not present.
+* `role="separator"`: a divider that separates and distinguishes sections of content or groups of menuitems..
+* `disabled"`: indicates that a menu item is disabled, otherwise not present.
+
+ 
+>The roles, states, and properties needed for the menu are described in more detail in WAI-ARIA Authoring Practices, [2.19 Menu or Menu bar](https://www.w3.org/TR/wai-aria-practices/#menu).
+
+## Events emitted from the component
+The menu button emits a custom `menuselect` event when a menu item is selected. The event has a detail object with the following structure:
+
+```javascript
+detail: { 
+  source: item // The selected menu item 
+}
+```
+
+To set up an event listener to receive the select custom event.
+```javascript
+document.querySelector('#my-menubutton').addEventListener('menuselect', function(e) {
+  console.log('menu item selected:', e.detail.source);
+});
+```
+Refer to [snippets/menu-button.html](./snippets/menu-button.html) or the [tests](../../test/menu-button/menu-button.spec.js) for detailed usage.
+
+
+## Public methods
+
+### openMenu(position)
+Open menu at given position. Position is on of `first`, `last` or `selected`. Default value is `first`.
+* `first` focus first menu item
+* `last` focus last menu item
+* `selected` focus previously selected menu item
+
+```javascript
+const menuButton = document.querySelector('#my-menu-button');
+menuButton.MaterialExtMenuButton.openMenu();
+```
+
+### closeMenu()
+Closes an open menu. Moves focus to button.
+
+```javascript
+const menuButton = document.querySelector('#my-menu-button');
+menuButton.MaterialExtMenuButton.closeMenu();
+```
+
+### getMenuElement()
+Get the menu element controlled by this button, null if no menu is controlled by this button.
+
+```javascript
+const menuButton = document.querySelector('#my-menu-button');
+const menu = menuButton.MaterialExtMenuButton.getMenuElement(); 
+```
+
+### getSelectedMenuItem()
+Get a selected menu item element, null if no menu item element selected.
+
+```javascript
+const menuButton = document.querySelector('#my-menu-button');
+const element = menuButton.MaterialExtMenuButton.getSelectedMenuItem();
+console.log('Selected menu item', element);
+```
+
+### setSelectedMenuItem(item)
+Set a selected menu item element, typically before menu is opened.
+
+```javascript
+const menuButton = document.querySelector('#my-menu-button');
+const menu = menuButton.MaterialExtMenuButton.getMenuElement(); 
+menuButton.MaterialExtMenuButton.setSelectedMenuItem(menu.children[1]);
+```
+
+Refer to [snippets/menu-button.html](./snippets/menu-button.html) or the [tests](../../test/menu-button/menu-button.spec.js) for detailed usage.
+
+## Configuration options
+
+The MDLEXT CSS classes apply various predefined visual and behavioral enhancements to the menu button. 
+The table below lists the available classes and their effects.
+
+| MDLEXT class                     | Effect | Remarks |
+|----------------------------------|--------|---------|
+|`mdlext-menu-button`              | Basic styling for a menu button | Optional on a div element |
+|`mdlext-js-menu-button`           | Assigns basic MDLEXT behavior to menu button. Identifies the element as a menu button component | Required on the element that should act as a menu button |
+|`mdlext-menu-button__caption`     | Holds the button text | Optional on span element inside menu button element - but required if you want to decorate a button with icons. More than one caption can be used to control various aspects of the button text, e.g. font size. |
+|`material-icons`                  | Defines span as a material icon | Required on an inline element. Decorates button or menu item with an icon |
+|`mdlext-menu`                     | Defines an unordered list container as an MDLEXT component | Required on ul element |
+|`mdlext-menu__item`               | Defines menu options | Required on list item elements |
+|`mdlext-menu__item__caption`      | Holds the menu text | Optional on span element inside list item element - but required if you want to decorate a menu item with icons. More than one caption can be used to control various aspects of the menu text, e.g. font size. |
+|`mdlext-menu__item-separator`     | Items in a menu may be divided into groups by placing an element with a role of `separator` between groups. | Optional; goes on unordered list element |
+|`mdlext-aria-expanded-plus-minus` | State icon. Displays '+' or '-' | Optional; goes on button element |
+|`mdlext-aria-expanded-more-less`  | State icon. Displays 'more' or 'less' Material Design icons | Optional; goes on button element |
+
+> **Note:** 
+> Disabled versions of the menu items are provided, and are invoked with the standard HTML boolean attribute `disabled` 
+`<li class="mdlext-menu__item" disabled>A menu item</li>`. This attribute may be added or removed programmatically via scripting.
+
+> If you decorate the menu button with icons, wrap the button text inside a span to separate icons and text 
+```html
+<button class="mdl-button mdl-button--raised mdl-js-ripple-effect mdl-js-button mdlext-js-menu-button">
+  <i class="material-icons">gesture</i>
+  <span class="mdlext-menu-button__caption">Select</span>
+  <i class="material-icons mdlext-menu-button__aria-expanded-more-less"></i>
+</button>
+```
+
+> If you decorate a menu item with icons, wrap the menu item text inside a span to separate icons and text 
+```html
+<ul id="demo-menu" class="mdlext-menu" hidden>
+  <li class="mdlext-menu__item">
+    <i class="material-icons md-18">help_outline</i>
+    <span class="mdlext-menu__item__caption">Menu item</span>
+    <i class="material-icons">info</i>
+  </li>
+</ul>
+```
diff --git a/node_modules/mdl-ext/src/menu-button/snippets/menu-button.html b/node_modules/mdl-ext/src/menu-button/snippets/menu-button.html
new file mode 100644
index 0000000..784f280
--- /dev/null
+++ b/node_modules/mdl-ext/src/menu-button/snippets/menu-button.html
@@ -0,0 +1,594 @@
+<article>
+<p>A menu button is a button that opens a menu. It is often styled as a typical push button with a
+downward pointing arrow or triangle to hint that activating the button will display a menu.
+The menu button has roles, attributes and behaviour as outlined in
+<a href="https://www.w3.org/TR/wai-aria-practices/#menubutton" target="_blank">WAI-ARIA Authoring Practices</a>.
+</p>
+</article>
+
+<link rel="stylesheet" href="http://code.ionicframework.com/ionicons/2.0.1/css/ionicons.min.css">
+
+<style>
+  .size-22 {
+    font-size: 22px;
+    width: 22px;
+    text-align: center;
+    vertical-align: middle;
+  }
+
+  .mdl-cell p {
+    margin-bottom: 0;
+    white-space: nowrap;
+    text-overflow: ellipsis;
+    overflow: hidden;
+  }
+
+
+  .mdl-textfield.mdlext-js-menu-button .mdl-textfield__input {
+    padding-right: 40px;
+  }
+
+  .mdl-textfield__icon {
+    width: 32px;
+    text-align: left;
+    position: absolute;
+    right: 0;
+    top: 50%;
+    transform: translateY(-50%);
+  }
+
+  .mdl-textfield.is-disabled .mdl-textfield__icon {
+    color: rgba(0, 0, 0, 0.26) !important;
+  }
+
+  .mdl-textfield.is-invalid .mdl-textfield__icon {
+    color: #de3226 !important;
+  }
+
+  #max-width-menu {
+    max-width: 400px;
+  }
+
+</style>
+
+<script>
+  function signedIn(sn) {
+    return 'Signed in with&nbsp;&nbsp;<i class="size-22 icon ion-social-' + sn + '"></i>&nbsp;';
+  }
+  function signedInIcon(sn) {
+    return '<i class="size-22 icon ion-social-' + sn + '"></i>';
+  }
+</script>
+
+<div class="mdl-grid mdl-grid--no-spacing">
+  <div class="mdl-cell mdl-cell--4-col">
+    <p><code>mdl-button</code></p>
+    <button id="btn-social-1" style="width:100%; max-width:300px; height:46px"
+            class="mdl-button mdl-button--colored mdl-button--raised mdl-js-ripple-effect mdl-js-button mdlext-js-menu-button"
+            aria-controls="shared-social-menu" >
+      <i class="material-icons">person_outline</i>
+      <span class="mdlext-menu-button__caption">Sign in with ...</span>
+      <i class="material-icons mdlext-aria-expanded-more-less"></i>
+    </button>
+    <script>
+      document.querySelector('#btn-social-1').addEventListener('menuselect', function(event) {
+        this.querySelector('.mdlext-menu-button__caption').innerHTML = signedIn(event.detail.source.getAttribute('data-value'));
+      });
+    </script>
+  </div> <!--cell -->
+
+  <div class="mdl-cell mdl-cell--4-col">
+    <p><code>mdl-textfield</code></p>
+    <div id="btn-social-2"
+         class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label mdlext-js-menu-button"
+         aria-controls="shared-social-menu">
+      <input class="mdl-textfield__input" type="text" readonly>
+      <label class="mdl-textfield__label">Sign in with ...</label>
+      <i class="material-icons mdl-textfield__icon mdlext-aria-expanded-more-less"></i>
+    </div>
+    <script>
+      document.querySelector('#btn-social-2').addEventListener('menuselect', function(event) {
+        this.MaterialTextfield.change(event.detail.source.querySelector('span').innerHTML);
+      });
+    </script>
+  </div> <!--cell -->
+
+  <div class="mdl-cell mdl-cell--4-col mdlext-bordered-fields">
+    <p><code>mdlext-bordered-fields</code></p>
+    <div id="btn-social-3"
+         class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label mdlext-bordered-fields__icon-right mdlext-js-menu-button"
+         aria-controls="shared-social-menu">
+      <input class="mdl-textfield__input" type="text" readonly>
+      <label class="mdl-textfield__label">Sign in with ...</label>
+      <i class="material-icons mdlext-aria-expanded-more-less"></i>
+    </div>
+    <script>
+      document.querySelector('#btn-social-3').addEventListener('menuselect', function(event) {
+        this.MaterialTextfield.change(event.detail.source.querySelector('span').innerHTML);
+      });
+    </script>
+  </div> <!--cell -->
+
+  <div class="mdl-cell mdl-cell--4-col">
+    <p>custom styled <code>&lt;div&gt;</code></p>
+    <div id="btn-social-4"
+         class="mdlext-menu-button mdlext-js-menu-button" style="width:300px; height:46px; max-width:100%;  border:1px solid green"
+         aria-controls="shared-social-menu">
+      <span class="mdlext-menu-button__caption">Sign in with ...</span>
+      <i class="material-icons mdlext-aria-expanded-more-less"></i>
+    </div>
+    <script>
+      document.querySelector('#btn-social-4').addEventListener('menuselect', function(event) {
+        this.querySelector('span').innerHTML = signedIn(event.detail.source.getAttribute('data-value')) + ', ' +
+          event.detail.source.querySelector('span').innerHTML;
+      });
+    </script>
+  </div> <!--cell -->
+
+
+  <div class="mdl-cell mdl-cell--4-col">
+    <p>mdl-button--icon</p>
+
+    <button id="btn-social-5" style="height:46px; width:46px;"
+            class="mdl-button mdl-js-button mdl-button--icon mdlext-js-menu-button"
+            aria-controls="shared-social-menu">
+      <i class="material-icons">more_vert</i>
+    </button>
+    <script>
+      document.querySelector('#btn-social-5').addEventListener('menuselect', function(event) {
+        this.innerHTML = signedInIcon(event.detail.source.getAttribute('data-value'));
+      });
+    </script>
+
+  </div> <!--cell -->
+
+</div> <!-- grid -->
+
+<ul id="shared-social-menu" class="mdlext-menu" hidden >
+  <li class="mdlext-menu__item" data-value="twitter">
+    <span class="mdlext-menu__item__caption">Twitter</span>
+    <i class="icon ion-social-twitter-outline size-22"></i>
+  </li>
+  <li class="mdlext-menu__item" data-value="github">
+    <span class="mdlext-menu__item__caption">GitHub</span>
+    <i class="ion-social-github-outline size-22"></i>
+  </li>
+  <li class="mdlext-menu__item" data-value="googleplus">
+    <span class="mdlext-menu__item__caption">G+</span>
+    <i class="ion-social-googleplus-outline size-22"></i>
+  </li>
+  <li class="mdlext-menu__item" data-value="linkedin">
+    <span class="mdlext-menu__item__caption">LinkedIn</span>
+    <i class="icon ion-social-linkedin-outline size-22"></i>
+  </li>
+  <li class="mdlext-menu__item" data-value="facebook">
+    <span class="mdlext-menu__item__caption">Facebook</span>
+    <i class="icon ion-social-facebook-outline size-22"></i>
+  </li>
+</ul>
+
+<p style="margin-top: 16px;">Menu buttons positioned left, middle and right, using <code>textalign</code>.</p>
+<div role="presentation">
+  <button class="mdl-button mdl-button--raised mdl-js-ripple-effect mdl-js-button mdlext-js-menu-button">
+    <i class="material-icons">gesture</i>
+    <span class="mdlext-menu-button__caption">Select</span>
+    <i class="material-icons mdlext-aria-expanded-more-less"></i>
+  </button>
+  <ul id="max-width-menu" class="mdlext-menu" hidden >
+    <li class="mdlext-menu__item">
+      <i class="material-icons md-18">info</i>
+      <span class="mdlext-menu__item__caption">Menu item #1</span>
+    </li>
+    <li class="mdlext-menu__item">
+      <i class="material-icons md-18">help_outline</i>
+      <span class="mdlext-menu__item__caption">Menu item #2. A long text to check ellipsis overflow 0123456789</span>
+      <i class="material-icons md-18">radio</i>
+    </li>
+    <li class="mdlext-menu__item-separator"></li>
+    <li class="mdlext-menu__item" disabled>
+      <span class="mdlext-menu__item__caption">Menu item #3, disabled</span>
+      <i class="material-icons md-18">accessibility</i>
+    </li>
+    <li class="mdlext-menu__item-separator"></li>
+    <li class="mdlext-menu__item">
+      <span class="mdlext-menu__item__caption">Menu item #IV</span>
+      <i class="material-icons md-18">build</i>
+    </li>
+    <li class="mdlext-menu__item">
+      <span class="mdlext-menu__item__caption">Menu item #V</span>
+      <i class="material-icons md-18">build</i>
+    </li>
+    <li class="mdlext-menu__item-separator"></li>
+    <li class="mdlext-menu__item">
+      <span class="mdlext-menu__item__caption">Menu item #VI</span>
+      <i class="material-icons md-18">build</i>
+    </li>
+    <li class="mdlext-menu__item">
+      <span class="mdlext-menu__item__caption">Menu item #VII</span>
+      <i class="material-icons md-18">build</i>
+    </li>
+    <li class="mdlext-menu__item">
+      Menu item #n
+    </li>
+  </ul>
+</div>
+
+
+<div role="presentation" style="text-align: center">
+  <button class="mdl-button mdl-button--raised mdl-js-ripple-effect mdl-js-button mdlext-js-menu-button">
+    <i class="material-icons">gesture</i>
+    <span class="mdlext-menu-button__caption">Select</span>
+    <i class="material-icons mdlext-aria-expanded-more-less"></i>
+  </button>
+  <ul class="mdlext-menu" hidden >
+    <li class="mdlext-menu__item">
+      <i class="material-icons md-18">info</i>
+      <span class="mdlext-menu__item__caption">Menu item #1</span>
+    </li>
+    <li class="mdlext-menu__item">
+      <i class="material-icons md-18">help_outline</i>
+      <span class="mdlext-menu__item__caption">Menu item #2</span>
+      <i class="material-icons md-18">radio</i>
+    </li>
+    <li class="mdlext-menu__item" disabled>
+      <span class="mdlext-menu__item__caption">Menu item #3, disabled</span>
+      <i class="material-icons md-18">accessibility</i>
+    </li>
+    <li class="mdlext-menu__item-separator"></li>
+    <li class="mdlext-menu__item">
+      <span class="mdlext-menu__item__caption">Menu item #IV</span>
+      <i class="material-icons md-18">build</i>
+    </li>
+    <li class="mdlext-menu__item">
+      <span class="mdlext-menu__item__caption">Menu item #V</span>
+      <i class="material-icons md-18">build</i>
+    </li>
+    <li class="mdlext-menu__item">
+      <span class="mdlext-menu__item__caption">Menu item #VI</span>
+      <i class="material-icons md-18">build</i>
+    </li>
+    <li class="mdlext-menu__item">
+      <span class="mdlext-menu__item__caption">Menu item #VII</span>
+      <i class="material-icons md-18">build</i>
+    </li>
+    <li class="mdlext-menu__item">
+      <span class="mdlext-menu__item__caption">Menu item #VIII</span>
+      <i class="material-icons md-18">build</i>
+    </li>
+    <li class="mdlext-menu__item">
+      <span class="mdlext-menu__item__caption">Menu item #IX</span>
+      <i class="material-icons md-18">build</i>
+    </li>
+    <li class="mdlext-menu__item">
+      <span class="mdlext-menu__item__caption">Menu item #X</span>
+      <i class="material-icons md-18">build</i>
+    </li>
+    <li class="mdlext-menu__item">
+      <span class="mdlext-menu__item__caption">Menu item #XI</span>
+      <i class="material-icons md-18">build</i>
+    </li>
+    <li class="mdlext-menu__item">
+      <span class="mdlext-menu__item__caption">Menu item #XII</span>
+      <i class="material-icons md-18">build</i>
+    </li>
+    <li class="mdlext-menu__item">
+      <span class="mdlext-menu__item__caption">Menu item #XIII</span>
+      <i class="material-icons md-18">build</i>
+    </li>
+    <li class="mdlext-menu__item">
+      <span class="mdlext-menu__item__caption">Menu item #XIV</span>
+      <i class="material-icons md-18">build</i>
+    </li>
+    <li class="mdlext-menu__item">
+      <span class="mdlext-menu__item__caption">Menu item #XV</span>
+      <i class="material-icons md-18">build</i>
+    </li>
+    <li class="mdlext-menu__item">
+      <span class="mdlext-menu__item__caption">Menu item #XVI</span>
+      <i class="material-icons md-18">build</i>
+    </li>
+    <li class="mdlext-menu__item">
+      <span class="mdlext-menu__item__caption">Menu item #XVII</span>
+      <i class="material-icons md-18">build</i>
+    </li>
+    <li class="mdlext-menu__item">
+      <span class="mdlext-menu__item__caption">Menu item #XVIII</span>
+      <i class="material-icons md-18">build</i>
+    </li>
+    <li class="mdlext-menu__item">
+      <span class="mdlext-menu__item__caption">Menu item #XIX</span>
+      <i class="material-icons md-18">build</i>
+    </li>
+    <li class="mdlext-menu__item">
+      <span class="mdlext-menu__item__caption">Menu item #XX</span>
+      <i class="material-icons md-18">build</i>
+    </li>
+    <li class="mdlext-menu__item">
+      Menu item #n
+    </li>
+  </ul>
+</div>
+
+
+<div role="presentation" style="text-align: right">
+  <button class="mdl-button mdl-button--raised mdl-js-ripple-effect mdl-js-button mdlext-js-menu-button">
+    <i class="material-icons">gesture</i>
+    <span class="mdlext-menu-button__caption">Select</span>
+    <i class="material-icons mdlext-aria-expanded-more-less"></i>
+  </button>
+  <ul class="mdlext-menu" hidden >
+    <li class="mdlext-menu__item">
+      <i class="material-icons md-18">info</i>
+      <span class="mdlext-menu__item__caption">Menu item #1</span>
+    </li>
+    <li class="mdlext-menu__item">
+      <i class="material-icons md-18">help_outline</i>
+      <span class="mdlext-menu__item__caption">Menu item #2</span>
+      <i class="material-icons md-18">radio</i>
+    </li>
+    <li class="mdlext-menu__item" disabled>
+      <span class="mdlext-menu__item__caption">Menu item #3, disabled</span>
+      <i class="material-icons md-18">accessibility</i>
+    </li>
+    <li class="mdlext-menu__item">
+      <span class="mdlext-menu__item__caption">Menu item #IV</span>
+      <i class="material-icons md-18">build</i>
+    </li>
+    <li class="mdlext-menu__item-separator"></li>
+    <li class="mdlext-menu__item">
+      <span class="mdlext-menu__item__caption">Menu item #V</span>
+      <i class="material-icons md-18">build</i>
+    </li>
+    <li class="mdlext-menu__item">
+      <span class="mdlext-menu__item__caption">Menu item #VI</span>
+      <i class="material-icons md-18">build</i>
+    </li>
+    <li class="mdlext-menu__item">
+      <span class="mdlext-menu__item__caption">Menu item #VII</span>
+      <i class="material-icons md-18">build</i>
+    </li>
+    <li class="mdlext-menu__item">
+      Menu item #n
+    </li>
+  </ul>
+</div>
+
+
+<p style="margin-top: 16px">This menu button has WAIA roles and attributes coded in markup</p>
+<button id="aria-demo-button"
+        class="mdl-button mdl-button--raised mdl-button--accent mdl-js-ripple-effect mdl-js-button mdlext-js-menu-button"
+        role="button"
+        aria-haspopup="true"
+        aria-controls="menu-example-dropdown"
+        aria-expanded="false"
+        tabindex="0">
+  <span class="mdlext-menu-button__caption">Select a size</span>
+  <i class="mdlext-aria-expanded-plus-minus"></i>
+</button>
+<script>
+  document.querySelector('#aria-demo-button').addEventListener('menuselect', function(event) {
+    this.querySelector('span').innerHTML = 'Size: ' + event.detail.source.innerHTML;
+  });
+</script>
+<ul id="menu-example-dropdown"
+    class="mdlext-menu"
+    role="menu"
+    hidden >
+  <li class="mdlext-menu__item" role="menuitem">X Small</li>
+  <li class="mdlext-menu__item-separator" role="separator"></li>
+  <li class="mdlext-menu__item" role="menuitem">Small</li>
+  <li class="mdlext-menu__item" role="menuitem">Medium</li>
+  <li class="mdlext-menu__item" role="menuitem">Large</li>
+  <li class="mdlext-menu__item-separator" role="separator"></li>
+  <li class="mdlext-menu__item" role="menuitem">X Large</li>
+  <li class="mdlext-menu__item" role="menuitem">XXX Large</li>
+</ul>
+
+<p style="margin-top: 16px">A disabled menu button should do nothing</p>
+<div role="presentation">
+  <button class="mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect mdlext-js-menu-button" disabled>
+    <span class="mdlext-menu-button__caption">Disabled</span>
+    <i class="material-icons mdlext-aria-expanded-more-less"></i>
+  </button>
+  <ul class="mdlext-menu" hidden>
+    <li class="mdlext-menu__item">Menu item #1</li>
+  </ul>
+</div>
+
+
+<p style="margin-top: 16px">Menu buttons inside a table. Menus placed inside and after the table element to verify
+  that positioning works as expected.</p>
+
+<div style="position:relative; border:2px solid green; overflow: hidden;">
+<p>The box with green borders has <code>overflow:hidden</code></p>
+<div>
+
+  <table id="a-table-with-menu-buttons"
+         class="mdl-data-table mdl-js-data-table mdl-data-table--selectable mdl-shadow--2dp" style="width: 48%; float:left;">
+  <thead>
+  <tr>
+    <th class="mdl-data-table__cell--non-numeric">Material</th>
+    <th>Quantity</th>
+    <th>Unit price</th>
+  </tr>
+  </thead>
+  <tbody>
+  <tr>
+    <td class="mdl-data-table__cell--non-numeric">Acrylic (Transparent)</td>
+    <td>
+      <span style="width:40px; display: inline-block;"></span>
+      <button class="mdl-button mdl-js-button mdl-button--icon mdl-button--primary mdlext-js-menu-button"
+              aria-controls="table-menu-example">
+        <i class="mdlext-aria-expanded-more-less"></i>
+      </button>
+    </td>
+    <td>$2.90</td>
+  </tr>
+  <tr>
+    <td class="mdl-data-table__cell--non-numeric">Plywood (Birch)</td>
+    <td>
+      <span style="width:40px; display: inline-block;"></span>
+      <button class="mdl-button mdl-js-button mdl-button--icon mdl-button--primary mdlext-js-menu-button"
+              aria-controls="table-menu-example">
+        <i class="mdlext-aria-expanded-more-less"></i>
+      </button>
+    </td>
+    <td>$1.25</td>
+  </tr>
+  <tr>
+    <td class="mdl-data-table__cell--non-numeric">Laminate (Gold on Blue)</td>
+    <td>
+      <span style="width:40px; display: inline-block;"></span>
+      <button class="mdl-button mdl-button--icon mdl-button--primary mdl-js-button mdlext-js-menu-button"
+              aria-controls="table-menu-example">
+        <i class="mdlext-aria-expanded-more-less"></i>
+      </button>
+    </td>
+    <td>$2.35</td>
+  </tr>
+  </tbody>
+  </table>
+
+  <script>
+    document.querySelector('#a-table-with-menu-buttons').addEventListener('menuselect', function(event) {
+      var span = event.target.closest('td').querySelector('span');
+      span.innerHTML = event.detail.source.getAttribute('data-value');
+    });
+  </script>
+
+  <div role="presentation" style="width:48%; float:right;">
+    <p style="margin-top: 16px">This menu button has a menu with dark color theme, <code>mdlext-dark-color-theme</code> class</p>
+
+    <button class="mdl-button mdl-button--raised mdl-js-ripple-effect mdl-js-button mdlext-js-menu-button">
+      <i class="material-icons">gesture</i>
+      <span class="mdlext-menu-button__caption">Select</span>
+      <i class="material-icons mdlext-aria-expanded-more-less"></i>
+    </button>
+    <ul class="mdlext-menu mdlext-dark-color-theme" hidden >
+      <li class="mdlext-menu__item">
+        <i class="material-icons md-18">info</i>
+        <span class="mdlext-menu__item__caption">Menu item #1</span>
+      </li>
+      <li class="mdlext-menu__item">
+        <i class="material-icons md-18">help_outline</i>
+        <span class="mdlext-menu__item__caption">Menu item #2. A long text to check ellipsis overflow 0123456789</span>
+        <i class="material-icons md-18">radio</i>
+      </li>
+      <li class="mdlext-menu__item-separator"></li>
+      <li class="mdlext-menu__item" disabled>
+        <span class="mdlext-menu__item__caption">Menu item #3, disabled</span>
+        <i class="material-icons md-18">accessibility</i>
+      </li>
+      <li class="mdlext-menu__item-separator"></li>
+      <li class="mdlext-menu__item">
+        <span class="mdlext-menu__item__caption">Menu item #IV</span>
+        <i class="material-icons md-18">build</i>
+      </li>
+      <li class="mdlext-menu__item">
+        <span class="mdlext-menu__item__caption">Menu item #V</span>
+        <i class="material-icons md-18">build</i>
+      </li>
+      <li class="mdlext-menu__item-separator"></li>
+      <li class="mdlext-menu__item">
+        <span class="mdlext-menu__item__caption">Menu item #VI</span>
+        <i class="material-icons md-18">build</i>
+      </li>
+    </ul>
+  </div>
+
+</div>
+</div>
+
+<ul id="table-menu-example" class="mdlext-menu" hidden >
+  <li class="mdlext-menu__item" data-value="10">Ten</li>
+  <li class="mdlext-menu__item" data-value="25">Twentyfive</li>
+  <li class="mdlext-menu__item" data-value="50">Fifty</li>
+</ul>
+
+
+<style>
+  .demo-grid {
+    margin-top: 32px;
+  }
+  .demo-grid .mdl-cell {
+    background: rgb(63,81,181);
+    text-align: center;
+    color: white;
+    padding: 16px 8px;
+    border: 1px solid #aaaaaa;
+  }
+  .demo-grid .mdl-cell:nth-child(odd) {
+    background: rgb(33,150,243);
+  }
+</style>
+
+
+<div id="a-grid-with-menu-buttons" class="demo-grid">
+  <p>Menu buttons inside <code>mdl-grid</code></p>
+
+  <div id="menu-button-grid" class="mdl-grid mdl-grid--no-spacing">
+    <div class="mdl-cell mdl-cell--4-col mdl-cell--4-col-tablet mdl-cell--2-col-phone">
+      <button class="mdl-button mdl-button--raised mdl-button--accent mdl-js-ripple-effect mdl-js-button mdlext-js-menu-button">
+        <span class="mdlext-menu-button__caption">Select a size</span>
+        <i class="mdlext-aria-expanded-plus-minus"></i>
+      </button>
+      <ul class="mdlext-menu"
+          role="menu"
+          hidden >
+        <li class="mdlext-menu__item" role="menuitem">Small</li>
+        <li class="mdlext-menu__item" role="menuitem">Medium</li>
+        <li class="mdlext-menu__item" role="menuitem">Large</li>
+      </ul>
+    </div>
+    <div class="mdl-cell mdl-cell--5-col mdl-cell--4-col-tablet mdl-cell--2-col-phone">
+      <button class="mdl-button mdl-button--raised mdl-button--accent mdl-js-ripple-effect mdl-js-button mdlext-js-menu-button">
+        <span class="mdlext-menu-button__caption">Select a size</span>
+        <i class="mdlext-aria-expanded-plus-minus"></i>
+      </button>
+      <ul class="mdlext-menu"
+          role="menu"
+          hidden >
+        <li class="mdlext-menu__item" role="menuitem">Small</li>
+        <li class="mdlext-menu__item" role="menuitem">Medium</li>
+        <li class="mdlext-menu__item" role="menuitem">Large</li>
+      </ul>
+    </div>
+    <div class="mdl-cell mdl-cell--3-col mdl-cell--4-col-tablet mdl-cell--hide-phone">
+      <button class="mdl-button mdl-button--raised mdl-button--accent mdl-js-ripple-effect mdl-js-button mdlext-js-menu-button">
+        <span class="mdlext-menu-button__caption">Select a size</span>
+        <i class="mdlext-aria-expanded-plus-minus"></i>
+      </button>
+      <ul class="mdlext-menu"
+          role="menu"
+          hidden >
+        <li class="mdlext-menu__item" role="menuitem">Small</li>
+        <li class="mdlext-menu__item" role="menuitem">Medium</li>
+        <li class="mdlext-menu__item" role="menuitem">Large</li>
+      </ul>
+    </div>
+  </div>
+</div>
+<script>
+  document.querySelector('#a-grid-with-menu-buttons').addEventListener('menuselect', function(event) {
+    event.target.querySelector('span').innerHTML = 'Size: ' + event.detail.source.innerHTML;
+  });
+</script>
+
+<div style="margin-bottom:256px;"></div>
+
+<!--
+https://www.w3.org/TR/wai-aria-practices/#menubutton
+http://w3c.github.io/aria-practices/examples/menu-button/menu-button-1.html
+http://w3c.github.io/aria-practices/examples/menu-button/menu-button-2.html
+http://tympanus.net/codrops/2012/10/04/custom-drop-down-list-styling/
+http://www.slideshare.net/webaxe/html5-dev-con-2012-aria-widget
+http://terrillthompson.com/blog/474
+https://github.com/davidtheclark/react-aria-menubutton
+https://codepen.io/tiffanytse/pen/Dkvtr
+https://codepen.io/andytran/pen/vLNGvN
+https://codepen.io/dapacreative/pen/WQoLzb
+https://codepen.io/gabrieltomescu/pen/ZGGyPK
+https://codepen.io/Idered/pen/vowrB
+https://codepen.io/Stedesign/pen/DbAJh
+http://markbirbeck.com/2015/10/14/a-mixin-approach-to-material-design-lite-using-sass/
+-->
diff --git a/node_modules/mdl-ext/src/selectfield/_selectfield.scss b/node_modules/mdl-ext/src/selectfield/_selectfield.scss
new file mode 100644
index 0000000..cd4ecfc
--- /dev/null
+++ b/node_modules/mdl-ext/src/selectfield/_selectfield.scss
@@ -0,0 +1,273 @@
+/**
+ * Copyright 2016 Leif Olsen. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * Copied/Modified/Inspired from/by:
+ *   https://github.com/google/material-design-lite/tree/master/src/textfield
+ *   http://red-team-design.com/making-html-dropdowns-not-suck/
+ *   http://codepen.io/etcpe9/pen/PqyOye,
+ *   http://codepen.io/pudgereyem/pen/PqBxQx
+ *   https://github.com/MEYVN-digital/mdl-selectfield
+ *   https://github.com/mebibou/mdl-selectfield
+ */
+
+// Use of this module requires the user to include variables from material-design-lite
+//@import "../../node_modules/material-design-lite/src/variables";
+//@import "../../node_modules/material-design-lite/src/mixins";
+
+@import "../mixins";
+
+// The container for the selectfield.
+.mdlext-selectfield {
+  box-sizing: border-box;
+  position: relative;
+  font-size: $input-text-font-size;
+  display: inline-block;
+  width: 300px;
+  max-width: 100%;
+  margin: 0;
+  padding: $input-text-vertical-spacing 0;
+
+  // Align buttons, if used.
+  & .mdl-button {
+    bottom: $input-text-vertical-spacing;
+    position: absolute;
+  }
+
+  // Styling the down arrow
+  &::after {
+    @include mdlext-arrow(bottom, $mdlext-selectfield-arrow-width, $mdlext-selectfield-arrow-length);
+
+    position: absolute;
+    right: 0.5em;
+    top: 50%;
+    transform: translateY(-50%);
+    pointer-events: none;
+  }
+}
+
+.mdlext-selectfield.is-disabled {
+  &::after {
+    color: $input-text-disabled-color;
+    @include mdlext-arrow(bottom, $mdlext-selectfield-arrow-width, $mdlext-selectfield-arrow-length, $input-text-disabled-color);
+  }
+}
+
+// Optional class to align right.
+.mdlext-selectfield--align-right {
+  text-align: right;
+}
+
+// Optional class to display at full width.
+.mdlext-selectfield--full-width {
+  width: 100%;
+}
+
+// Optional class to make the select field expandable.
+.mdlext-selectfield--expandable {
+  min-height: $input-text-button-size;
+  min-width: $input-text-button-size;
+  width: auto;
+}
+
+// Styling for the select element.
+.mdlext-selectfield__select {
+
+  // Reset select
+  box-sizing: border-box;
+  border: 0;
+  border-radius: 0;
+  -webkit-appearance: none;
+  -moz-appearance: none;
+  -ms-appearance: none;
+  appearance: none;
+  text-indent: 0.01px; // Removes default arrow from firefox
+  text-overflow: '';   // Removes default arrow from firefox
+  outline: none;
+  box-shadow: none;
+  // End Reset select
+
+  font-size: $input-text-font-size;
+  font-family: $performance_font;
+  padding: $input-text-padding calc(1.2em + #{$input-text-padding}) $input-text-padding 0;
+  width: $input-text-width;
+  border-bottom: 1px solid $input-text-bottom-border-color;
+  display: block;
+  margin: 0;
+  background: none;
+  text-align: left;
+  color: inherit;
+
+  // Mozilla, remove focusring
+  &:-moz-focusring {
+    color: transparent;
+    text-shadow: 0 0 0 #000000;
+  }
+
+  // MS, remove selected option background color
+  &:focus::-ms-value {
+    background-color: inherit;
+    color: inherit;
+  }
+
+  &::-ms-expand {
+    display: none;
+  }
+
+  .mdlext-selectfield.is-focused & {
+    outline: none;
+  }
+
+  .mdlext-selectfield.is-invalid & {
+    border-color: $input-text-error-color;
+    box-shadow: none;
+  }
+
+  fieldset[disabled] .mdlext-selectfield &,
+  .mdlext-selectfield.is-disabled & {
+    border-bottom: 1px dotted $input-text-disabled-color;
+    color: $input-text-disabled-text-color;
+    background-color: transparent;
+  }
+
+  option {
+    color: $text-color-primary;
+    box-sizing: border-box;
+    background-color: inherit;
+  }
+}
+
+// Styling for the label / floating label.
+.mdlext-selectfield__label {
+  box-sizing: border-box;
+  color: $input-text-label-color;
+  font-size: $input-text-font-size;
+  top: ($input-text-padding + $input-text-vertical-spacing);
+  bottom: 0;
+  left: 0;
+  right: 0;
+  pointer-events: none;
+  position: absolute;
+  display: block;
+  width: 100%;
+  overflow: hidden;
+  white-space: nowrap;
+  text-align: left;
+
+  .mdlext-selectfield.is-dirty &,
+  .mdlext-selectfield.has-placeholder & {
+    visibility: hidden;
+  }
+
+  // Floating Label
+  .mdlext-selectfield--floating-label & {
+    @include material-animation-default();
+  }
+
+  .mdlext-selectfield--floating-label.has-placeholder & {
+    transition: none;
+  }
+
+  fieldset[disabled] .mdlext-selectfield &,
+  .mdlext-selectfield.is-disabled.is-disabled & {
+    color: $input-text-disabled-text-color;
+  }
+
+  .mdlext-selectfield--floating-label.is-focused &,
+  .mdlext-selectfield--floating-label.is-dirty.is-dirty &,
+  .mdlext-selectfield--floating-label.has-placeholder & {
+    color: $input-text-highlight-color;
+    font-size: $input-text-floating-label-fontsize;
+    top: $input-text-vertical-spacing - ($input-text-floating-label-fontsize + $input-text-padding);
+    visibility: visible;
+  }
+
+  .mdlext-selectfield--floating-label.is-focused .mdlext-selectfield__expandable-holder &,
+  .mdlext-selectfield--floating-label.is-dirty .mdlext-selectfield__expandable-holder &,
+  .mdlext-selectfield--floating-label.has-placeholder .mdlext-selectfield__expandable-holder & {
+    top: -($input-text-floating-label-fontsize + $input-text-padding);
+  }
+
+  .mdlext-selectfield--floating-label.is-invalid & {
+    color: $input-text-error-color;
+    font-size: $input-text-floating-label-fontsize;
+  }
+
+  // The after label is the colored underline for the Selectfield.
+  &::after {
+    background-color: $input-text-highlight-color;
+    bottom: $input-text-vertical-spacing;
+    content: '';
+    height: 2px;
+    left: 45%;
+    position: absolute;
+    @include material-animation-default();
+
+    visibility: hidden;
+    width: 10px;
+  }
+
+  .mdlext-selectfield.is-focused &::after {
+    left: 0;
+    visibility: visible;
+    width: 100%;
+  }
+
+  .mdlext-selectfield.is-invalid &::after {
+    background-color: $input-text-error-color;
+  }
+}
+
+// SelectField Error.
+.mdlext-selectfield__error {
+  color: $input-text-error-color;
+  font-size: $input-text-floating-label-fontsize;
+  position: absolute;
+  margin-top: 3px;
+  visibility: hidden;
+  display: block;
+
+  .mdlext-selectfield.is-invalid & {
+    visibility: visible;
+  }
+}
+
+// Expandable Holder.
+.mdlext-selectfield__expandable-holder {
+  display: inline-block;
+  position: relative;
+  margin-left: $input-text-button-size;
+
+  @include material-animation-default();
+
+  // Safari (possibly others) need to be convinced that this field is actually
+  // visible, otherwise it cannot be tabbed to nor focused via a <label>.
+  // TODO: In some cases (Retina displays), this is big enough to render the
+  // inner element :(
+  max-width: 0.1px;
+
+  .mdlext-selectfield.is-focused &,
+  .mdlext-selectfield.is-dirty & {
+    // This is an unfortunate hack. Animating between widths in percent (%)
+    // in many browsers (Chrome, Firefox) only animates the inner visual style
+    // of the input - the outer bounding box still 'jumps'.
+    // Thus assume a sensible maximum, and animate to/from that value.
+    max-width: 600px;
+  }
+  .mdlext-selectfield__label::after {
+    bottom: 0;
+  }
+}
diff --git a/node_modules/mdl-ext/src/selectfield/readme.md b/node_modules/mdl-ext/src/selectfield/readme.md
new file mode 100644
index 0000000..891ea36
--- /dev/null
+++ b/node_modules/mdl-ext/src/selectfield/readme.md
@@ -0,0 +1,152 @@
+# Selectfield
+![Selectfield](../../etc/select-element.png)
+
+## Introduction
+The [HTML select](https://developer.mozilla.org/en/docs/Web/HTML/Element/select) (`<select>`) element represents 
+a control that presents a menu of options. The options within the menu are represented by `<option>` elements, 
+which can be grouped by `<optgroup>` elements. Options can be pre-selected for the user.
+
+The Material Design Lite Ext (MDLEXT) **select field** component is an enhanced version of the standard 
+[HTML `<select>`] (https://developer.mozilla.org/en/docs/Web/HTML/Element/select) element.
+A select field consists of a horizontal line indicating where keyboard input can occur and, typically, text that clearly communicates 
+the intended contents of the select field. An icon (at the right hand side) indicates that the select field has user selectable options. 
+
+This component relates to the guidelines given in [Materials Design spesifications page, Text Fields](http://www.google.com/design/spec/components/text-fields.html). 
+
+### To include a MDLEXT **select field** component:
+
+&nbsp;1. Code a `<div>` element to hold the select field.
+```html
+<div>
+...
+</div>
+```
+
+&nbsp;2. Inside the div, code an `<select>` element with an `id` attribute of your choice.
+```html
+<div>
+  <select id="some-id">
+  </select>
+</div>
+```
+
+&nbsp;3. Inside the `<select>` element code a list of user selectable options.
+```html
+<div>
+  <select id="some-id">
+    <option value=""></option>
+    <option value="option1">option 1</option>
+    <option value="option2">option 2</option>
+    <option value="option3">option 3</option>
+  </select>
+</div>
+```
+
+&nbsp;4. Also inside the div, after the `<select>` element, code a `<label>` element with a `for` attribute 
+whose value matches the `select` element's `id` value, and a short string to be used as the field's placeholder text.
+```html
+<div>
+  <select id="some-id">
+  ...
+  </select>
+  <label for="some-id">Options</label>
+</div>
+```
+
+&nbsp;5. Add one or more MDLEXT classes, separated by spaces, to the select field container, 
+select element, label element, and error message using the `class` attribute.
+```html
+<div class="mdlext-selectfield mdlext-js-selectfield">
+  <select id="some-id" class="mdlext-selectfield__select">
+  ...
+  </select>
+  <label for="some-id" class="mdlext-selectfield__label">Options</label>
+  <span class="mdlext-selectfield__error">Someting is wrong</span>
+</div>
+```
+The select field component is ready for use.
+
+#### Examples
+
+Select field with a standard label.
+```html
+<div class="mdlext-selectfield mdlext-js-selectfield">
+  <select id="some-id" class="mdlext-selectfield__select">
+    <option value=""></option>
+    <option value="option1">option 1</option>
+    <option value="option2">option 2</option>
+    <option value="option3">option 3</option>
+  </select>
+  <label for="some-id" class="mdlext-selectfield__label">Options</label>
+</div>
+```
+
+Select field with a floating label.
+```html
+<div class="mdlext-selectfield mdlext-js-selectfield mdlext-selectfield--floating-label">
+  <select id="some-id" class="mdlext-selectfield__select">
+    <option value=""></option>
+    <option value="option1">option 1</option>
+    <option value="option2">option 2</option>
+    <option value="option3">option 3</option>
+  </select>
+  <label for="some-id" class="mdlext-selectfield__label">Options</label>
+</div>
+```
+
+Select field with a standard label and error message.
+```html
+<div class="mdlext-selectfield mdlext-js-selectfield">
+  <select id="some-id" class="mdlext-selectfield__select">
+    <option value=""></option>
+    <option value="option1">option 1</option>
+    <option value="option2">option 2</option>
+    <option value="option3">option 3</option>
+  </select>
+  <label for="some-id" class="mdlext-selectfield__label">Options</label>
+  <span class="mdlext-selectfield__error">Something is wrong</span>
+</div>
+```
+
+
+## Configuration options
+
+The MDLEXT CSS classes apply various predefined visual and behavioral enhancements to the select field. 
+The table below lists the available classes and their effects.
+
+| MDLEXT class | Effect | Remarks |
+|-----------|--------|---------|
+| `mdlext-selectfield` | Defines container as an MDL component | Required on "outer" div element|
+| `mdlext-js-selectfield` | Assigns basic MDL behavior to input | Required on "outer" div element |
+| `mdlext-selectfield__select` | Defines element as selectfield select | Required on select element |
+| `mdlext-selectfield__label` | Defines element as selectfield label | Required on label element for select elements |
+| `mdlext-selectfield--floating-label` | Applies *floating label* effect | Optional; goes on "outer" div element |
+| `mdlext-selectfield__error` | Defines span as an MDL error message | Optional; goes on span element for MDL select element with *pattern*|
+| `is-invalid` | Defines the selectfield as invalid on initial load. | Optional on `mdlext-selectfield` element |
+<!--
+| `mdlext-selectfield--expandable` | Defines a div as an MDL expandable select field container | For expandable select fields, required on "outer" div element |
+| `mdl-button` | Defines label as an MDL icon button | For expandable select fields, required on "outer" div's label element |
+| `mdl-js-button` | Assigns basic behavior to icon container | For expandable input fields, required on "outer" div's label element |
+| `mdl-button--icon` | Defines label as an MDL icon container | For expandable select fields, required on "outer" div's label element |
+| `mdl-input__expandable-holder` | Defines a container as an MDL component | For expandable select fields, required on "inner" div element |
+-->
+
+>**Note I:** Disabled versions of each select field type are provided, and are invoked with the standard HTML boolean attribute `disabled`. `<select class="mdlext-selectfield__select" id="select-id" name="select-id" disabled>`
+>This attribute may be added or removed programmatically via scripting.
+
+>**Note II:** The select field can for some browser and OS combinations, e.g. 
+>FireFox and OSX, be off by 2 pixels compared to the input field. There is no 
+>way to fix this, as far as I know, without setting an explicit height on both field types. 
+>Since MDL does not set a specific height of the text field, it can not be done for the select 
+>field either. If alignment is required, the user must in his/hers design set a specific height 
+>both for textfields and selectfields.
+
+## How to use the component programmatically
+The tests provides examples on how to use the component [programmatically](https://github.com/leifoolsen/mdl-ext/blob/master/test/selectfield/selectfield.spec.js)
+
+### Credits 
+The Select component is based on the following sources:
+* [Material Design Lite selectfield component](https://github.com/mebibou/mdl-selectfield) 
+* [mdl-selectfield](https://github.com/MEYVN-digital/mdl-selectfield)
+* [Simple Material Design Login, with select field](http://codepen.io/michaelschofield/pen/qEzWaM)
+* [Material Design &lt;select&gt; element, css only](http://codepen.io/pudgereyem/pen/PqBxQx)
diff --git a/node_modules/mdl-ext/src/selectfield/selectfield.js b/node_modules/mdl-ext/src/selectfield/selectfield.js
new file mode 100644
index 0000000..459f0b8
--- /dev/null
+++ b/node_modules/mdl-ext/src/selectfield/selectfield.js
@@ -0,0 +1,277 @@
+/**
+ * @license
+ * Copyright 2016 Leif Olsen. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * This code is built with Google Material Design Lite,
+ * which is Licensed under the Apache License, Version 2.0
+ */
+
+/*
+ * Copied/Modified from https://github.com/google/material-design-lite/tree/master/src/textfield
+ */
+
+import { randomString } from '../utils/string-utils';
+import {
+  IS_DIRTY,
+  IS_FOCUSED,
+  IS_DISABLED,
+  IS_INVALID,
+  IS_UPGRADED
+} from '../utils/constants';
+
+(function() {
+  'use strict';
+  const LABEL = 'mdlext-selectfield__label';
+  const INPUT = 'mdlext-selectfield__select';
+
+  /**
+   * Class constructor for Selectfield MDLEXT component.
+   * Implements MDL component design pattern defined at:
+   * https://github.com/jasonmayes/mdl-component-design-pattern
+   *
+   * @constructor
+   * @param {HTMLElement} element The element that will be upgraded.
+   */
+  const MaterialExtSelectfield = function MaterialExtSelectfield(element) {
+    this.element_ = element;
+    this.init(); // Initialize instance.
+  };
+
+  window['MaterialExtSelectfield'] = MaterialExtSelectfield;
+
+  /**
+   * Handle focus.
+   *
+   * @param {Event} event The event that fired.
+   * @private
+   */
+  /*eslint no-unused-vars: 0*/
+  MaterialExtSelectfield.prototype.onFocus_ = function( /*event*/ ) {
+    this.element_.classList.add(IS_FOCUSED);
+  };
+
+  /**
+   * Handle lost focus.
+   *
+   * @param {Event} event The event that fired.
+   * @private
+   */
+  /*eslint no-unused-vars: 0*/
+  MaterialExtSelectfield.prototype.onBlur_ = function( /*event*/ ) {
+    this.element_.classList.remove(IS_FOCUSED);
+  };
+
+  /**
+   * Handle reset event from out side.
+   *
+   * @param {Event} event The event that fired.
+   * @private
+   */
+  MaterialExtSelectfield.prototype.onReset_ = function( /*event*/ ) {
+    this.updateClasses_();
+  };
+
+  /**
+   * Handle class updates.
+   *
+   * @private
+   */
+  MaterialExtSelectfield.prototype.updateClasses_ = function() {
+    this.checkDisabled();
+    this.checkValidity();
+    this.checkDirty();
+    this.checkFocus();
+  };
+
+  // Public methods.
+
+  /**
+   * Check the disabled state and update field accordingly.
+   *
+   * @public
+   */
+  MaterialExtSelectfield.prototype.checkDisabled = function() {
+    if (this.select_.disabled) {
+      this.element_.classList.add(IS_DISABLED);
+    } else {
+      this.element_.classList.remove(IS_DISABLED);
+    }
+  };
+  MaterialExtSelectfield.prototype['checkDisabled'] = MaterialExtSelectfield.prototype.checkDisabled;
+
+
+  /**
+   * Check the focus state and update field accordingly.
+   *
+   * @public
+   */
+  MaterialExtSelectfield.prototype.checkFocus = function() {
+    // Note: element.querySelector(':focus') always return null in JsDom, even if select element has focus
+    /*eslint no-extra-boolean-cast: 0*/
+    if (Boolean(this.element_.querySelector(':focus'))) {
+      this.element_.classList.add(IS_FOCUSED);
+    } else {
+      this.element_.classList.remove(IS_FOCUSED);
+    }
+  };
+
+  MaterialExtSelectfield.prototype['checkFocus'] = MaterialExtSelectfield.prototype.checkFocus;
+
+
+  /**
+   * Check the validity state and update field accordingly.
+   *
+   * @public
+   */
+  MaterialExtSelectfield.prototype.checkValidity = function() {
+
+    /* Don't think it makes any sense to check validity.
+       Tests I've done, so far, indicates that setting an illegal value via JS returns selectedIndex=0
+
+    if (this.select_.validity) {
+      if (this.select_.validity.valid) {
+        this.element_.classList.remove(this.CssClasses_.IS_INVALID);
+      } else {
+        this.element_.classList.add(this.CssClasses_.IS_INVALID);
+      }
+    }
+    */
+  };
+
+  MaterialExtSelectfield.prototype['checkValidity'] = MaterialExtSelectfield.prototype.checkValidity;
+
+  /**
+   * Check the dirty state and update field accordingly.
+   *
+   * @public
+   */
+  MaterialExtSelectfield.prototype.checkDirty = function() {
+    if (this.select_.value && this.select_.value.length > 0) {
+      this.element_.classList.add(IS_DIRTY);
+    } else {
+      this.element_.classList.remove(IS_DIRTY);
+    }
+  };
+
+  MaterialExtSelectfield.prototype['checkDirty'] = MaterialExtSelectfield.prototype.checkDirty;
+
+  /**
+   * Disable select field.
+   *
+   * @public
+   */
+  MaterialExtSelectfield.prototype.disable = function() {
+    this.select_.disabled = true;
+    this.updateClasses_();
+  };
+
+  MaterialExtSelectfield.prototype['disable'] = MaterialExtSelectfield.prototype.disable;
+
+  /**
+   * Enable select field.
+   *
+   * @public
+   */
+  MaterialExtSelectfield.prototype.enable = function() {
+    this.select_.disabled = false;
+    this.updateClasses_();
+  };
+
+  MaterialExtSelectfield.prototype['enable'] = MaterialExtSelectfield.prototype.enable;
+
+  /**
+   * Update select field value.
+   *
+   * @param {string} value The value to which to set the control (optional).
+   * @public
+   */
+  MaterialExtSelectfield.prototype.change = function(value) {
+    this.select_.value = value || '';
+    this.updateClasses_();
+  };
+  MaterialExtSelectfield.prototype['change'] = MaterialExtSelectfield.prototype.change;
+
+  /**
+   * Initialize element.
+   */
+  MaterialExtSelectfield.prototype.init = function() {
+    if (this.element_) {
+      this.label_ = this.element_.querySelector(`.${LABEL}`);
+      this.select_ = this.element_.querySelector(`.${INPUT}`);
+
+      if (this.select_) {
+        // Remove listeners, just in case ...
+        this.select_.removeEventListener('change', this.updateClasses_);
+        this.select_.removeEventListener('focus', this.onFocus_);
+        this.select_.removeEventListener('blur', this.onBlur_);
+        this.select_.removeEventListener('reset', this.onReset_);
+
+        this.select_.addEventListener('change', this.updateClasses_.bind(this));
+        this.select_.addEventListener('focus', this.onFocus_.bind(this));
+        this.select_.addEventListener('blur', this.onBlur_.bind(this));
+        this.select_.addEventListener('reset', this.onReset_.bind(this));
+
+        if(this.label_) {
+          let id;
+          if(!this.select_.hasAttribute('id')) {
+            id = `select-${randomString()}`;
+            this.select_.id = id;
+          }
+          else {
+            id = this.select_.id;
+          }
+
+          if(!this.label_.hasAttribute('for')) {
+            this.label_.setAttribute('for', id);
+          }
+        }
+
+        const invalid = this.element_.classList.contains(IS_INVALID);
+        this.updateClasses_();
+        this.element_.classList.add(IS_UPGRADED);
+
+        if (invalid) {
+          this.element_.classList.add(IS_INVALID);
+        }
+        if (this.select_.hasAttribute('autofocus')) {
+          this.element_.focus();
+          this.checkFocus();
+        }
+      }
+    }
+  };
+
+  /**
+   * Downgrade component
+   * E.g remove listeners and clean up resources
+   *
+   * Nothing to downgrade
+   *
+  MaterialExtSelectfield.prototype.mdlDowngrade_ = function() {
+    'use strict';
+    console.log('***** MaterialExtSelectfield.mdlDowngrade ');
+  };
+  */
+
+  // The component registers itself. It can assume componentHandler is available
+  // in the global scope.
+  /*eslint no-undef: 0*/
+  componentHandler.register({
+    constructor: MaterialExtSelectfield,
+    classAsString: 'MaterialExtSelectfield',
+    cssClass: 'mdlext-js-selectfield',
+    widget: true
+  });
+})();
diff --git a/node_modules/mdl-ext/src/selectfield/snippets/selectfield.html b/node_modules/mdl-ext/src/selectfield/snippets/selectfield.html
new file mode 100644
index 0000000..d9bc5cd
--- /dev/null
+++ b/node_modules/mdl-ext/src/selectfield/snippets/selectfield.html
@@ -0,0 +1,113 @@
+<p>The<a href="https://developer.mozilla.org/en/docs/Web/HTML/Element/select" target="_blank">
+  HTML select</a> (&lt;select&gt;) element represents a control that presents a menu of options.
+  The options within the menu are represented by &lt;option&gt; elements, which can be grouped by
+  &lt;optgroup&gt; elements. Options can be pre-selected for the user.</p>
+
+<p>The Material Design Lite Ext (MDLEXT) <strong>select field</strong> component is an enhanced version of the standard
+  HTML &lt;select&gt; element. A select field consists of a horizontal line indicating where keyboard input
+  can occur and, typically, text that clearly communicates the intended contents of the select field.
+  An icon (at the right hand side) indicates that the select field has user selectable options.</p>
+
+<p><strong>Note: </strong>
+  The select field can for some browser and OS combinations, e.g. FireFox and OSX, be off by 2 pixels compared to the
+  input field. There is no way to fix this, as far as I know, without setting an explicit height on both field types.
+  Since MDL does not set a specific height of the text field, it can not be done for the select field either.
+  If alignment is required, the user must in his/hers design set a specific height both for textfields and selectfields.
+</p>
+
+<style scoped>
+  .selectelement-demo-container {
+  }
+  .selectelement-demo-container .mdl-cell {
+    padding: 0 4px 16px 0;
+  }
+  .selectelement-demo-container .mdl-cell p {
+    margin-bottom: 0;
+    white-space: nowrap;
+    text-overflow: ellipsis;
+    overflow: hidden;
+  }
+</style>
+
+<div class = "selectelement-demo-container">
+
+  <div class="mdl-grid mdl-grid--no-spacing">
+
+    <div class="mdl-cell mdl-cell--3-col">
+      <p>Selectfield component</p>
+      <div class="mdlext-selectfield mdlext-js-selectfield">
+        <select class="mdlext-selectfield__select">
+          <option value=""></option>
+          <option value="option1">option 1</option>
+          <option value="option2">option 2</option>
+          <option value="option3">option 3</option>
+          <option value="option4">option 4</option>
+          <option value="option5">option 5</option>
+          <option value="option6">option 5 abcdefghijklmnopqrstuvw0123456789</option>
+        </select>
+        <label class="mdlext-selectfield__label">Profession</label>
+      </div>
+    </div>
+
+    <div class="mdl-cell mdl-cell--3-col">
+      <p>Textfield component</p>
+      <div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label">
+        <input class="mdl-textfield__input" type="text">
+        <label class="mdl-textfield__label">... to check alignment</label>
+      </div>
+    </div>
+
+    <div class="mdl-cell mdl-cell--3-col">
+      <p>Selectfield component with floating label</p>
+      <div class="mdlext-selectfield mdlext-js-selectfield mdlext-selectfield--floating-label">
+        <select class="mdlext-selectfield__select">
+          <option value=""></option>
+          <option value="option1">option 1</option>
+          <option value="option2">option 2</option>
+          <option value="option3">option 3</option>
+          <option value="option4">option 4</option>
+          <option value="option5">option 5</option>
+          <option value="option6">option 5 abcdefghijklmnopqrstuvw0123456789</option>
+        </select>
+        <label class="mdlext-selectfield__label">Profession</label>
+      </div>
+    </div>
+
+    <div class="mdl-cell mdl-cell--3-col">
+      <p>Disabled selectfield component</p>
+      <div class="mdlext-selectfield mdlext-js-selectfield mdlext-selectfield--floating-label">
+        <select class="mdlext-selectfield__select" disabled>
+          <option value=""></option>
+          <option value="option1">option 1</option>
+          <option value="option2">option 2</option>
+          <option value="option3">option 3</option>
+          <option value="option4">option 4</option>
+          <option value="option5">option 5</option>
+          <option value="option6">option 5 abcdefghijklmnopqrstuvw0123456789</option>
+        </select>
+        <label class="mdlext-selectfield__label">Profession</label>
+      </div>
+    </div>
+
+    <div class="mdl-cell mdl-cell--3-col">
+      <p>Unstyled select element</p>
+      <select style="width: 100%;">
+        <option value=""></option>
+        <option value="option1">option 1</option>
+        <option value="option2">option 2</option>
+        <option value="option3">option 3</option>
+        <option value="option4">option 4</option>
+        <option value="option5">option 5</option>
+        <option value="option6">option 5 abcdefghijklmnopqrstuvw0123456789</option>
+      </select>
+      <label>Profession</label>
+    </div>
+
+    <div class="mdl-cell mdl-cell--3-col">
+      <p>Unstyled input element</p>
+      <input type="text" style="width: 100%;">
+      <label>... to check alignment</label>
+    </div>
+
+  </div>
+</div>
diff --git a/node_modules/mdl-ext/src/sticky-header/_sticky-header.scss b/node_modules/mdl-ext/src/sticky-header/_sticky-header.scss
new file mode 100644
index 0000000..69a36f7
--- /dev/null
+++ b/node_modules/mdl-ext/src/sticky-header/_sticky-header.scss
@@ -0,0 +1,52 @@
+/**
+ * Copyright 2016 Leif Olsen. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// Use of this module requires the user to include variables from material-design-lite
+//@import "../../node_modules/material-design-lite/src/variables";
+//@import "../../node_modules/material-design-lite/src/mixins";
+@import "../variables";
+
+.mdlext-layout__sticky-header {
+  position: absolute;
+  overflow: visible;
+  background: $mdlext-sticky-header-background;
+  transition: 0.1s ease-in-out;
+
+  &.mdlext-is-scroll {
+    background: $mdlext-sticky-header-background-scroll;
+  }
+}
+
+*:not(.is-small-screen) .mdlext-layout__sticky-header {
+  .mdl-layout__drawer-button {
+    visibility: hidden;
+  }
+  .mdl-layout__header-row {
+    padding-left: $padding;
+  }
+}
+
+*:not(.mdl-layout--fixed-drawer).has-drawer .mdlext-layout__sticky-header,
+.is-small-screen.has-drawer .mdlext-layout__sticky-header {
+  display: flex;
+
+  .mdl-layout__drawer-button {
+    visibility: visible;
+  }
+  .mdl-layout__header-row {
+    padding-left: $padding + $layout-drawer-button-desktop-size;
+  }
+}
diff --git a/node_modules/mdl-ext/src/sticky-header/readme.md b/node_modules/mdl-ext/src/sticky-header/readme.md
new file mode 100644
index 0000000..e9b3107
--- /dev/null
+++ b/node_modules/mdl-ext/src/sticky-header/readme.md
@@ -0,0 +1,172 @@
+# Sticky Header
+
+![Sticky Header](../../etc/sticky-header.png)
+
+A sticky header can be used as a replacement for the Material Design Lite 
+[Fixed Header](https://github.com/google/material-design-lite/tree/master/src/layout#examples).
+
+## Introduction
+A sticky header makes site navigation easily accessible anywhere on the page and saves content space at the same.
+
+The header should auto-hide, i.e. hiding the header automatically when a user starts scrolling down the page and 
+bringing the header back when a user might need it: they reach the bottom of the page or start scrolling up.
+
+>**Note:** The Sticky Header does not collapse on smaller screens.
+
+### To include a MDLEXT **sticky-header** component:
+
+&nbsp;1. Code a `<div>` element. This is the "outer" div that holds the entire layout.
+```html
+<div>
+</div>
+```
+
+&nbsp;2. Add MDL classes as indicated, separated by spaces, to the `div` using the class attribute.
+```html
+<div class="mdl-layout mdl-js-layout mdl-layout--fixed-drawer mdl-layout--fixed-header">
+</div>
+```
+
+&nbsp;3. Inside the div, code a `<header>` element, as described in the Material Design Lite 
+[Component Guide](https://getmdl.io/components/index.html#layout-section/layout). Add MDL classes as indicated.
+```html
+<div class="mdl-layout mdl-js-layout mdl-layout--fixed-drawer mdl-layout--fixed-header">
+  <header class="mdl-layout__header mdlext-layout__sticky-header mdlext-js-sticky-header">
+    <div class="mdl-layout__header-row">
+  
+      <!-- Title -->
+      <span id="header-title" class="mdl-layout-title">Title goes here</span>
+  
+      <!-- Add spacer, to align navigation to the right -->
+      <div class="mdl-layout-spacer"></div>
+  
+      <label id="go-home" class="mdl-button mdl-js-button mdl-button--icon mdl-button--colored">
+        <a href="#">
+          <i class="material-icons">home</i>
+        </a>
+      </label>
+    </div>
+  </header>
+</div>
+```
+
+&nbsp;4. Code a drawer, and include the MDL class as indicated
+```html
+<div class="mdl-layout mdl-js-layout mdl-layout--fixed-drawer mdl-layout--fixed-header">
+  <header class="mdl-layout__header mdlext-layout__sticky-header mdlext-js-sticky-header">
+    <div class="mdl-layout__header-row">
+  
+      <!-- Title -->
+      <span id="header-title" class="mdl-layout-title">Title goes here</span>
+  
+      <!-- Add spacer, to align navigation to the right -->
+      <div class="mdl-layout-spacer"></div>
+  
+      <label id="go-home" class="mdl-button mdl-js-button mdl-button--icon mdl-button--colored">
+        <a href="#">
+          <i class="material-icons">home</i>
+        </a>
+      </label>
+    </div>
+  </header>
+
+  <aside class="mdl-layout__drawer">
+    <span class="mdl-layout-title">Drawer title</span>
+    <nav class="mdl-navigation">
+      <a class="mdl-navigation__link" href="#">A manu item</a>
+    </nav>
+  </aside>
+</div>
+```
+
+&nbsp;4. Add a `<main>` element to hold the layout's primary content, and include the MDL class as indicated
+```html
+<div class="mdl-layout mdl-js-layout mdl-layout--fixed-drawer mdl-layout--fixed-header">
+  <header class="mdl-layout__header mdlext-layout__sticky-header mdlext-js-sticky-header">
+    <div class="mdl-layout__header-row">
+  
+      <!-- Title -->
+      <span id="header-title" class="mdl-layout-title">Title goes here</span>
+  
+      <!-- Add spacer, to align navigation to the right -->
+      <div class="mdl-layout-spacer"></div>
+  
+      <label id="go-home" class="mdl-button mdl-js-button mdl-button--icon mdl-button--colored">
+        <a href="#">
+          <i class="material-icons">home</i>
+        </a>
+      </label>
+    </div>
+  </header>
+
+  <aside class="mdl-layout__drawer">
+    <span class="mdl-layout-title">Drawer title</span>
+    <nav class="mdl-navigation">
+      <a class="mdl-navigation__link" href="#">A manu item</a>
+    </nav>
+  </aside>
+  
+  <main class="mdl-layout__content">
+    <p>Content</p>
+    <p>Goes</p>
+    <p>Here</p>
+  </main>  
+</div>
+```
+
+### Examples
+
+* [Sticky header, Fixed drawer](http://leifoolsen.github.io/mdl-ext/demo/sticky-header.html)
+* [Sticky header, Drawer](http://leifoolsen.github.io/mdl-ext/demo/sticky-header-ii.html)
+* [Sticky header, No Drawer](http://leifoolsen.github.io/mdl-ext/demo/sticky-header-iii.html)
+* [Sticky header, Waterfall, Fiexed Drawer](http://leifoolsen.github.io/mdl-ext/demo/sticky-header-iv.html)
+* [Sticky header, Waterfall, Drawer](http://leifoolsen.github.io/mdl-ext/demo/sticky-header-v.html)
+* [Sticky header, Waterfall, No Drawer](http://leifoolsen.github.io/mdl-ext/demo/sticky-header-vi.html)
+
+
+## Component configuration
+The component can be configured using a `data-config` attribute. The attribute value is a JSON string with the following properties.
+
+| Property             |    |    |
+|----------------------|----|----|
+| `visibleAtScrollEnd` | if `true`, the header vil show when page is scrolled to the bottom | default: `false` |
+
+
+The `data-config` attribute must be a valid JSON string. You can use single or double quotes for the JSON properties. 
+
+Example 1, single quotes in JSON config string:
+```html
+<header class="mdl-layout__header mdlext-layout__sticky-header mdlext-js-sticky-header" 
+  data-config="{ 'visibleAtScrollEnd': true }">
+  
+  <div class="mdl-layout__header-row">
+    <span id="header-title" class="mdl-layout-title">Title goes here</span>
+  </div>
+</header>
+```
+
+Example 2, double quotes in JSON config string:
+```html
+<header class="mdl-layout__header mdlext-layout__sticky-header mdlext-js-sticky-header" 
+  data-config='{ "visibleAtScrollEnd": true }'>
+  
+  <div class="mdl-layout__header-row">
+    <span id="header-title" class="mdl-layout-title">Title goes here</span>
+  </div>
+</header>
+```
+
+## Configuration options
+
+The MDLEXT CSS classes apply various predefined visual and behavioral enhancements to the lightbox.
+The table below lists the available classes and their effects.
+
+| MDLEXT class | Effect | Remarks |
+|--------------|--------|---------|
+| `mdlext-layout__sticky-header` | Defines a header as an MDLEXT header component | Required on `<header>` element |
+| `mdlext-js-sticky-header` | Assigns basic MDL behavior to header | Required on `<header>` element |
+
+
+## How to use the component programmatically
+The [tests](../../test/sticky-header/sticky-header.spec.js) provides example code on how to use the component programmatically.
+
diff --git a/node_modules/mdl-ext/src/sticky-header/sticky-header.js b/node_modules/mdl-ext/src/sticky-header/sticky-header.js
new file mode 100644
index 0000000..9ed2e13
--- /dev/null
+++ b/node_modules/mdl-ext/src/sticky-header/sticky-header.js
@@ -0,0 +1,251 @@
+/**
+ * @license
+ * Copyright 2016 Leif Olsen. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * This code is built with Google Material Design Lite,
+ * which is Licensed under the Apache License, Version 2.0
+ */
+
+/**
+ * A sticky header makes site navigation easily accessible anywhere on the page and saves content space at the same.
+ * The header should auto-hide, i.e. hiding the header automatically when a user starts scrolling down the page and
+ * bringing the header back when a user might need it: they reach the bottom of the page or start scrolling up.
+ */
+
+import fullThrottle from '../utils/full-throttle';
+import { jsonStringToObject } from '../utils/json-utils';
+import {
+  IS_UPGRADED
+} from '../utils/constants';
+
+
+(function() {
+  'use strict';
+  const MDL_LAYOUT_CONTENT  = 'mdl-layout__content';
+  const IS_SCROLL_CLASS  = 'mdlext-is-scroll';
+
+
+  /**
+   * @constructor
+   * @param {Element} element The element that will be upgraded.
+   */
+  const MaterialExtStickyHeader = function MaterialExtStickyHeader(element) {
+    // Stores the element.
+    this.header_ = element;
+
+    // Heder listens to scroll events from content
+    this.content_ = null;
+    this.lastScrollTop_ = 0;
+
+    // Default config
+    this.config_ = {
+      visibleAtScrollEnd: false
+    };
+
+    this.mutationObserver_ = null;
+
+    this.drawing_ = false;
+
+    // Initialize instance.
+    this.init();
+  };
+
+  window['MaterialExtStickyHeader'] = MaterialExtStickyHeader;
+
+
+  /**
+   * Update header width
+   * @private
+   */
+  MaterialExtStickyHeader.prototype.recalcWidth_ = function() {
+    this.header_.style.width = `${this.content_.clientWidth}px`;
+  };
+
+  const throttleResize = fullThrottle(self => self.recalcWidth_() );
+
+  /**
+   * Adjust header width when window resizes or oreientation changes
+   * @param event
+   * @private
+   */
+  MaterialExtStickyHeader.prototype.resizeHandler_ = function( /* event */ ) {
+    throttleResize(this);
+  };
+
+
+  /**
+   * Update header position
+   * @private
+   */
+  MaterialExtStickyHeader.prototype.reposition_ = function() {
+
+    const currentContentScrollTop = this.content_.scrollTop;
+    const scrollDiff = this.lastScrollTop_ - currentContentScrollTop;
+
+    if(currentContentScrollTop <= 0) {
+      // Scrolled to the top. Header sticks to the top
+      this.header_.style.top = '0';
+      this.header_.classList.remove(IS_SCROLL_CLASS);
+    }
+    else if(scrollDiff > 0) {
+
+      if(scrollDiff >= this.header_.offsetHeight) {
+
+        // Scrolled up. Header slides in
+        const headerTop = (parseInt( window.getComputedStyle( this.header_ ).getPropertyValue( 'top' ) ) || 0);
+        if(headerTop != 0) {
+          this.header_.style.top = '0';
+          this.header_.classList.add(IS_SCROLL_CLASS);
+        }
+        this.lastScrollTop_ = currentContentScrollTop;
+      }
+      return;
+    }
+    else if(scrollDiff < 0) {
+      // Scrolled down
+      this.header_.classList.add(IS_SCROLL_CLASS);
+      let headerTop = (parseInt( window.getComputedStyle( this.header_ ).getPropertyValue( 'top' ) ) || 0);
+
+      if (this.content_.scrollHeight - this.content_.scrollTop <= this.content_.offsetHeight) {
+        // Bottom of content
+        if(headerTop != 0) {
+          this.header_.style.top = this.config_.visibleAtScrollEnd ? '0' : `-${this.header_.offsetHeight}px`;
+        }
+      }
+      else {
+        headerTop += scrollDiff;
+        const offsetHeight = this.header_.offsetHeight;
+        this.header_.style.top = `${( Math.abs( headerTop ) > offsetHeight ? -offsetHeight : headerTop )}px`;
+      }
+    }
+
+    this.lastScrollTop_ = currentContentScrollTop;
+  };
+
+
+  const throttleScroll = fullThrottle((self) => self.reposition_());
+
+  /**
+   * Scroll header when content scrolls
+   * @param event
+   * @private
+   */
+  MaterialExtStickyHeader.prototype.scrollHandler_ = function( /* event */ ) {
+    throttleScroll(this);
+  };
+
+  /**
+   * Init header position
+   * @private
+   */
+  MaterialExtStickyHeader.prototype.updatePosition_ = function( /* event */ ) {
+    this.recalcWidth_();
+    this.reposition_();
+  };
+
+  /**
+   * Add mutation observer
+   * @private
+   */
+  MaterialExtStickyHeader.prototype.addMutationObserver_ = function() {
+
+    // jsdom does not support MutationObserver - so this is not testable
+    /* istanbul ignore next */
+    this.mutationObserver_ = new MutationObserver( ( /*mutations*/ ) => {
+      // Adjust header width if content changes (e.g. in a SPA)
+      this.updatePosition_();
+    });
+
+    this.mutationObserver_.observe( this.content_, {
+      attributes: false,
+      childList: true,
+      characterData: false,
+      subtree: true
+    });
+  };
+
+    /**
+   * Removes event listeners
+   * @private
+   */
+  MaterialExtStickyHeader.prototype.removeListeners_ = function() {
+
+    window.removeEventListener('resize', this.resizeHandler_);
+    window.removeEventListener('orientationchange', this.resizeHandler_);
+
+    if(this.content_) {
+      this.content_.removeEventListener('scroll', this.scrollHandler_);
+    }
+
+    if(this.mutationObserver_) {
+      this.mutationObserver_.disconnect();
+      this.mutationObserver_ = null;
+    }
+  };
+
+  /**
+   * Initialize component
+   */
+  MaterialExtStickyHeader.prototype.init = function() {
+
+    if (this.header_) {
+
+      this.removeListeners_();
+
+      if(this.header_.hasAttribute('data-config')) {
+        this.config_ = jsonStringToObject(this.header_.getAttribute('data-config'));
+      }
+
+      this.content_ = this.header_.parentNode.querySelector(`.${MDL_LAYOUT_CONTENT}`) || null;
+
+      if(this.content_) {
+        this.content_.style.paddingTop = `${this.header_.offsetHeight}px`;  // Make room for sticky header
+        this.lastScrollTop_ = this.content_.scrollTop;
+
+        this.content_.addEventListener('scroll', this.scrollHandler_.bind(this));
+        window.addEventListener('resize', this.resizeHandler_.bind(this));
+        window.addEventListener('orientationchange', this.resizeHandler_.bind(this));
+
+        this.addMutationObserver_();
+        this.updatePosition_();
+
+        // Set upgraded flag
+        this.header_.classList.add(IS_UPGRADED);
+      }
+    }
+  };
+
+  /*
+   * Downgrade component
+   * E.g remove listeners and clean up resources
+   *
+   * Nothing to clean
+   *
+   MaterialExtStickyHeader.prototype.mdlDowngrade_ = function() {
+     'use strict';
+     console.log('***** MaterialExtStickyHeader.prototype.mdlDowngrade_');
+   };
+   */
+
+
+  // The component registers itself. It can assume componentHandler is available
+  // in the global scope.
+  /* eslint no-undef: 0 */
+  componentHandler.register({
+    constructor: MaterialExtStickyHeader,
+    classAsString: 'MaterialExtStickyHeader',
+    cssClass: 'mdlext-js-sticky-header'
+  });
+})();
diff --git a/node_modules/mdl-ext/src/utils/constants.js b/node_modules/mdl-ext/src/utils/constants.js
new file mode 100644
index 0000000..9e63ea7
--- /dev/null
+++ b/node_modules/mdl-ext/src/utils/constants.js
@@ -0,0 +1,62 @@
+'use strict';
+
+const VK_TAB         = 9;
+const VK_ENTER       = 13;
+const VK_ESC         = 27;
+const VK_SPACE       = 32;
+const VK_PAGE_UP     = 33;
+const VK_PAGE_DOWN   = 34;
+const VK_END         = 35;
+const VK_HOME        = 36;
+const VK_ARROW_LEFT  = 37;
+const VK_ARROW_UP    = 38;
+const VK_ARROW_RIGHT = 39;
+const VK_ARROW_DOWN  = 40;
+
+const ARIA_EXPANDED        = 'aria-expanded';
+const ARIA_HIDDEN          = 'aria-hidden';
+const ARIA_MULTISELECTABLE = 'aria-multiselectable';
+const ARIA_SELECTED        = 'aria-selected';
+
+const IS_DIRTY      = 'is-dirty';
+const IS_DISABLED   = 'is-disabled';
+const IS_EXPANDED   = 'is-expanded';
+const IS_FOCUSED    = 'is-focused';
+const IS_INVALID    = 'is-invalid';
+const IS_UPGRADED   = 'is-upgraded';
+const DATA_UPGRADED = 'data-upgraded';
+
+const MDL_RIPPLE                      = 'mdl-ripple';
+const MDL_RIPPLE_COMPONENT            = 'MaterialRipple';
+const MDL_RIPPLE_EFFECT               = 'mdl-js-ripple-effect';
+const MDL_RIPPLE_EFFECT_IGNORE_EVENTS = 'mdl-js-ripple-effect--ignore-events';
+
+export {
+  VK_TAB,
+  VK_ENTER,
+  VK_ESC,
+  VK_SPACE,
+  VK_PAGE_UP,
+  VK_PAGE_DOWN ,
+  VK_END,
+  VK_HOME,
+  VK_ARROW_LEFT,
+  VK_ARROW_UP,
+  VK_ARROW_RIGHT,
+  VK_ARROW_DOWN ,
+  ARIA_EXPANDED,
+  ARIA_HIDDEN,
+  ARIA_MULTISELECTABLE,
+  ARIA_SELECTED,
+  IS_DIRTY,
+  IS_DISABLED,
+  IS_EXPANDED,
+  IS_FOCUSED,
+  IS_INVALID,
+  IS_UPGRADED,
+  DATA_UPGRADED ,
+  MDL_RIPPLE,
+  MDL_RIPPLE_COMPONENT,
+  MDL_RIPPLE_EFFECT,
+  MDL_RIPPLE_EFFECT_IGNORE_EVENTS
+};
diff --git a/node_modules/mdl-ext/src/utils/debounce-function.js b/node_modules/mdl-ext/src/utils/debounce-function.js
new file mode 100644
index 0000000..68ce449
--- /dev/null
+++ b/node_modules/mdl-ext/src/utils/debounce-function.js
@@ -0,0 +1,66 @@
+/**
+ * Debouncing enforces that a function not be called again until a certain
+ * amount of time has passed without it being called.
+ *
+ * @see https://css-tricks.com/the-difference-between-throttling-and-debouncing/
+ * @see https://github.com/webmodules/raf-debounce
+ * @see https://github.com/moszeed/es6-promise-debounce
+ * @see https://gist.github.com/philbirnie/893950093611d5c1dff4246a572cfbeb/
+ * @see https://github.com/SliceMeNice-ES6/event-utils/blob/master/debounce.js
+ * @see https://github.com/jeromedecoster/raf-funcs
+ * @see http://unscriptable.com/2009/03/20/debouncing-javascript-methods/
+ * @see http://davidwalsh.name/javascript-debounce-function
+ *
+ * @param callback the callback
+ * @param threshold optional delay, default to 250 ms, min to 1000/60ms ms
+ * @param context  optional context of this, default to global
+ * @return {Function} reference to immediate and cancel
+ */
+const MIN_THRESHOLD = 1000/60;
+
+const debounceFunction = function(callback, threshold=250, context) {
+
+  if(threshold < MIN_THRESHOLD) {
+    threshold = MIN_THRESHOLD;
+  }
+
+  if (!context) {
+    context = this || window;
+  }
+
+  let next = null;
+  let start = 0;
+
+  return function (...args) {
+
+    const cancel = () => {
+      if(next) {
+        window.cancelAnimationFrame(next);
+        next = null;
+      }
+    };
+
+    const execute = () => {
+      cancel();
+      return Reflect.apply(callback, context, args);
+    };
+
+    const later = () => {
+      if (threshold - (Date.now() - start) <= 0) {
+        return execute();
+      }
+      next = window.requestAnimationFrame(later);
+    };
+
+    cancel();
+    start = Date.now();
+    next = window.requestAnimationFrame(later);
+
+    return {
+      cancel: () => cancel(),
+      immediate: () => execute()
+    };
+  };
+};
+
+export default debounceFunction;
diff --git a/node_modules/mdl-ext/src/utils/dom-utils.js b/node_modules/mdl-ext/src/utils/dom-utils.js
new file mode 100644
index 0000000..5aa2658
--- /dev/null
+++ b/node_modules/mdl-ext/src/utils/dom-utils.js
@@ -0,0 +1,418 @@
+/**
+ * Remove child element(s)
+ * element.innerHTNL = '' has a performance penality!
+ * @see http://jsperf.com/empty-an-element/16
+ * @see http://jsperf.com/force-reflow
+ * @param element
+ * @param forceReflow
+ */
+const removeChildElements = (element, forceReflow = true) => {
+
+  // See: http://jsperf.com/empty-an-element/16
+  while (element.lastChild) {
+    element.removeChild(element.lastChild);
+  }
+  if(forceReflow) {
+    // See: http://jsperf.com/force-reflow
+    const d = element.style.display;
+
+    element.style.display = 'none';
+    element.style.display = d;
+  }
+};
+
+/**
+ * Moves child elements from a DOM node to another dom node.
+ * @param source {HTMLElement}
+ * @param target {HTMLElement} If the target parameter is ommited, a document fragment is created
+ * @return {HTMLElement} The target node
+ *
+ * @example
+ * // Moves child elements from a DOM node to another dom node.
+ * moveElements(source, destination);
+ *
+ * @example
+ * // If the second parameter is ommited, a document fragment is created:
+ * let fragment = moveElements(source);
+ *
+ * @See: https://github.com/webmodules/dom-move
+ */
+const moveElements = (source, target) => {
+  if (!target) {
+    target = source.ownerDocument.createDocumentFragment();
+  }
+  while (source.firstChild) {
+    target.appendChild(source.firstChild);
+  }
+  return target;
+};
+
+
+/**
+ * Get the browser viewport dimensions
+ * @see http://stackoverflow.com/questions/1248081/get-the-browser-viewport-dimensions-with-javascript
+ * @return {{windowWidth: number, windowHeight: number}}
+ */
+const getWindowViewport = () => {
+  return {
+    viewportWidth: Math.max(document.documentElement.clientWidth || 0, window.innerWidth || 0),
+    viewportHeight: Math.max(document.documentElement.clientHeight || 0, window.innerHeight || 0)
+  };
+};
+
+
+/**
+ * Check whether an element is in the window viewport
+ * @see http://stackoverflow.com/questions/123999/how-to-tell-if-a-dom-element-is-visible-in-the-current-viewport/
+ * @param top
+ * @param left
+ * @param bottom
+ * @param right
+ * @return {boolean} true if rectangle is inside window viewport, otherwise false
+ */
+const isRectInsideWindowViewport = ({ top, left, bottom, right }) => {
+  const { viewportWidth, viewportHeight } = getWindowViewport();
+  return top >= 0 &&
+    left >= 0 &&
+    bottom <= viewportHeight &&
+    right <= viewportWidth;
+};
+
+
+/**
+ * Get a list of parent elements that can possibly scroll
+ * @param el the element to get parents for
+ * @returns {Array}
+ */
+const getScrollParents = el => {
+  const elements = [];
+
+  /*
+  for (el = el.parentNode; el; el = el.parentNode) {
+    const cs = window.getComputedStyle(el);
+    if(!(cs.overflowY === 'hidden' && cs.overflowX === 'hidden')) {
+      elements.unshift(el);
+    }
+    if(el === document.body) {
+      break;
+    }
+  }
+  */
+
+  let element = el.parentNode;
+  while (element) {
+    const cs = window.getComputedStyle(element);
+    if(!(cs.overflowY === 'hidden' && cs.overflowX === 'hidden')) {
+      elements.unshift(element);
+    }
+    if(element === document.body) {
+      break;
+    }
+    element = element.parentNode;
+  }
+
+  return elements;
+};
+
+/**
+ * Get a list of parent elements, from a given element to a given element
+ * @param {HTMLElement} from
+ * @param {HTMLElement} to
+ * @return {Array<HTMLElement>} the parent elements, not including from and to
+ */
+const getParentElements = (from, to) => {
+  const result = [];
+  let element = from.parentNode;
+  while (element) {
+    if(element === to) {
+      break;
+    }
+    result.unshift(element);
+    element = element.parentNode;
+  }
+  return result;
+};
+
+/**
+ * Position element next to button
+ *
+ * Positioning strategy
+ *  1. element.height > viewport.height
+ *     let element.height = viewport.heigt
+ *     let element.overflow-y = auto
+ *  2. element.width > viewport.width
+ *     let element.width = viewport.width
+ *  3. position element below button, align left edge of element with button left
+ *       done if element inside viewport
+ *  4. position element below button, align right edge of element with button right
+ *       done if element inside viewport
+ *  5. positions element above button, aligns left edge of element with button left
+ *       done if element inside viewport
+ *  6. position element above the control element, aligned to its right.
+ *       done if element inside viewport
+ *  7. position element at button right hand side, aligns element top with button top
+ *       done if element inside viewport
+ *  8. position element at button left hand side, aligns element top with button top
+ *       done if element inside viewport
+ *  9. position element inside viewport
+ *     1. position element at viewport bottom
+ *     2. position element at button right hand side
+ *        done if element inside viewport
+ *     3. position element at button left hand side
+ *       done if element inside viewport
+ *     4. position element at viewport right
+ * 10. done
+ *
+ */
+const tether = (controlledBy, element) => {
+  const controlRect = controlledBy.getBoundingClientRect();
+
+  // 1. will element height fit inside window viewport?
+  const { viewportWidth, viewportHeight } = getWindowViewport();
+
+  element.style.height = 'auto';
+  //element.style.overflowY = 'hidden';
+  if(element.offsetHeight > viewportHeight) {
+    element.style.height = `${viewportHeight}px`;
+    element.style.overflowY = 'auto';
+  }
+
+  // 2. will element width fit inside window viewport?
+  element.style.width = 'auto';
+  if(element.offsetWidth > viewportWidth) {
+    element.style.width = `${viewportWidth}px`;
+  }
+
+  const elementRect = element.getBoundingClientRect();
+
+  // element to control distance
+  const dy = controlRect.top - elementRect.top;
+  const dx = controlRect.left - elementRect.left;
+
+  // element rect, window coordinates relative to top,left of control
+  const top = elementRect.top + dy;
+  const left = elementRect.left + dx;
+  const bottom = top + elementRect.height;
+  const right = left + elementRect.width;
+
+  // Position relative to control
+  let ddy = dy;
+  let ddx = dx;
+
+  if(isRectInsideWindowViewport({
+    top: top + controlRect.height,
+    left: left,
+    bottom: bottom + controlRect.height,
+    right: right
+  })) {
+    // 3 position element below the control element, aligned to its left
+    ddy = controlRect.height + dy;
+    //console.log('***** 3');
+  }
+  else if(isRectInsideWindowViewport({
+    top: top + controlRect.height,
+    left: left + controlRect.width - elementRect.width,
+    bottom: bottom + controlRect.height,
+    right: left + controlRect.width
+  })) {
+    // 4 position element below the control element, aligned to its right
+    ddy = controlRect.height + dy;
+    ddx = dx + controlRect.width - elementRect.width;
+    //console.log('***** 4');
+  }
+  else if(isRectInsideWindowViewport({
+    top: top - elementRect.height,
+    left: left,
+    bottom: bottom - elementRect.height,
+    right: right
+  })) {
+    // 5. position element above the control element, aligned to its left.
+    ddy = dy - elementRect.height;
+    //console.log('***** 5');
+  }
+  else if(isRectInsideWindowViewport({
+    top: top - elementRect.height,
+    left: left + controlRect.width - elementRect.width,
+    bottom: bottom - elementRect.height,
+    right: left + controlRect.width
+  })) {
+    // 6. position element above the control element, aligned to its right.
+    ddy = dy - elementRect.height;
+    ddx = dx + controlRect.width - elementRect.width;
+    //console.log('***** 6');
+  }
+  else if(isRectInsideWindowViewport({
+    top: top,
+    left: left + controlRect.width,
+    bottom: bottom,
+    right: right + controlRect.width
+  })) {
+    // 7. position element at button right hand side
+    ddx = controlRect.width + dx;
+    //console.log('***** 7');
+  }
+  else if(isRectInsideWindowViewport({
+    top: top,
+    left: left - controlRect.width,
+    bottom: bottom,
+    right: right - controlRect.width
+  })) {
+    // 8. position element at button left hand side
+    ddx = dx - elementRect.width;
+    //console.log('***** 8');
+  }
+  else {
+    // 9. position element inside viewport, near controlrect if possible
+    //console.log('***** 9');
+
+    // 9.1 position element near controlrect bottom
+    ddy =  dy - bottom + viewportHeight;
+    if(top + controlRect.height >= 0 && bottom + controlRect.height <= viewportHeight) {
+      ddy = controlRect.height + dy;
+    }
+    else if(top - elementRect.height >= 0 && bottom - elementRect.height <= viewportHeight) {
+      ddy = dy - elementRect.height;
+    }
+
+    if(left + elementRect.width + controlRect.width <= viewportWidth) {
+      // 9.2 Position element at button right hand side
+      ddx = controlRect.width + dx;
+      //console.log('***** 9.2');
+    }
+    else if(left - elementRect.width >= 0) {
+      // 9.3 Position element at button left hand side
+      ddx = dx - elementRect.width;
+      //console.log('***** 9.3');
+    }
+    else {
+      // 9.4 position element at (near) viewport right
+      const r = left + elementRect.width - viewportWidth;
+      ddx = dx - r;
+      //console.log('***** 9.4');
+    }
+  }
+
+  // 10. done
+  element.style.top = `${element.offsetTop + ddy}px`;
+  element.style.left = `${element.offsetLeft + ddx}px`;
+  //console.log('***** 10. done');
+};
+
+/**
+ * Check if the given element can receive focus
+ * @param {HTMLElement} element the element to check
+ * @return {boolean} true if the element is focusable, otherwise false
+ */
+const isFocusable = (element) => {
+  // https://github.com/stephenmathieson/is-focusable/blob/master/index.js
+  // http://stackoverflow.com/questions/1599660/which-html-elements-can-receive-focus
+
+  if (element.hasAttribute('tabindex')) {
+    const tabindex = element.getAttribute('tabindex');
+    if (!Number.isNaN(tabindex)) {
+      return parseInt(tabindex) > -1;
+    }
+  }
+
+  if (element.hasAttribute('contenteditable') &&
+    element.getAttribute('contenteditable') !== 'false') {
+    // https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes#attr-contenteditable
+    return true;
+  }
+
+  // natively focusable, but only when enabled
+  const selector = /input|select|textarea|button|details/i;
+  const name = element.nodeName;
+  if (selector.test(name)) {
+    return element.type.toLowerCase() !== 'hidden' && !element.disabled;
+  }
+
+  // anchors and area must have an href
+  if (name === 'A' || name === 'AREA') {
+    return !!element.href;
+  }
+
+  if (name === 'IFRAME') {
+    // Check visible iframe
+    const cs = window.getComputedStyle(element);
+    return cs.getPropertyValue('display').toLowerCase() !== 'none';
+  }
+
+  return false;
+};
+
+
+/**
+ * Get a list of offset parents for given element
+ * @see https://www.benpickles.com/articles/51-finding-a-dom-nodes-common-ancestor-using-javascript
+ * @param el the element
+ * @return {Array} a list of offset parents
+ */
+/*
+const offsetParents = (el) => {
+  const elements = [];
+  for (; el; el = el.offsetParent) {
+    elements.unshift(el);
+  }
+  if(!elements.find(e => e === document.body)) {
+    elements.unshift(document.body);
+  }
+  return elements;
+};
+*/
+
+/**
+ * Finds the common offset ancestor of two DOM nodes
+ * @see https://www.benpickles.com/articles/51-finding-a-dom-nodes-common-ancestor-using-javascript
+ * @see https://gist.github.com/benpickles/4059636
+ * @param a
+ * @param b
+ * @return {Element} The common offset ancestor of a and b
+ */
+/*
+const commonOffsetAncestor = (a, b) => {
+  const parentsA = offsetParents(a);
+  const parentsB = offsetParents(b);
+
+  for (let i = 0; i < parentsA.length; i++) {
+    if (parentsA[i] !== parentsB[i]) return parentsA[i-1];
+  }
+};
+*/
+
+/**
+ * Calculate position relative to a target element
+ * @see http://stackoverflow.com/questions/21064101/understanding-offsetwidth-clientwidth-scrollwidth-and-height-respectively
+ * @param target
+ * @param el
+ * @return {{top: number, left: number}}
+ */
+/*
+const calcPositionRelativeToTarget = (target, el) => {
+  let top = 0;
+  let left = 0;
+
+  while(el) {
+    top += (el.offsetTop - el.scrollTop + el.clientTop) || 0;
+    left += (el.offsetLeft - el.scrollLeft + el.clientLeft) || 0;
+    el = el.offsetParent;
+
+    if(el === target) {
+      break;
+    }
+  }
+  return { top: top, left: left };
+};
+*/
+
+export {
+  getWindowViewport,
+  getParentElements,
+  getScrollParents,
+  isFocusable,
+  isRectInsideWindowViewport,
+  moveElements,
+  removeChildElements,
+  tether,
+};
+
diff --git a/node_modules/mdl-ext/src/utils/easing.js b/node_modules/mdl-ext/src/utils/easing.js
new file mode 100644
index 0000000..fea208f
--- /dev/null
+++ b/node_modules/mdl-ext/src/utils/easing.js
@@ -0,0 +1,18 @@
+'use strict';
+
+// See: http://robertpenner.com/easing/
+
+const easeInOutQuad = (t, b, c, d) => {
+  t /= d / 2;
+  if(t < 1) return c / 2 * t * t + b;
+  t--;
+  return -c / 2 * (t * (t - 2) - 1) + b;
+};
+
+const inOutQuintic = (t, b, c, d) => {
+  const ts = (t/=d)*t;
+  const tc = ts*t;
+  return b+c*(6*tc*ts + -15*ts*ts + 10*tc);
+};
+
+export { easeInOutQuad, inOutQuintic };
diff --git a/node_modules/mdl-ext/src/utils/full-throttle.js b/node_modules/mdl-ext/src/utils/full-throttle.js
new file mode 100644
index 0000000..7cac3d7
--- /dev/null
+++ b/node_modules/mdl-ext/src/utils/full-throttle.js
@@ -0,0 +1,35 @@
+/**
+ * Since some events can fire at a high rate, the event handler should be limited to execute computationally
+ * expensive operations, such as DOM modifications, inside a single rendered frame.
+ * When listening to e.g. scroll and resize events, the browser tends to fire off more events per
+ * second than are actually useful. For instance, if your event listener sets some element positions, then it
+ * is possible for those positions to be updated multiple times in a single rendered frame. In this case, all of
+ * the layout calculations triggered by setting the elements' positions will be wasted except for the one time that
+ * it runs immediately prior to the browser rendering the updated layout to the screen.
+ * To avoid wasting cycles, we can use requestAnimationFrame to only run the event listener once just before the page
+ * is rendered to the screen.
+ * *
+ * @param callback the function to throttle
+ * @param context  optional context of this, default to global
+ * @return {function(...[*])}
+ */
+const fullThrottle = (callback, context) => {
+
+  if (!context) {
+    context = this || window;
+  }
+
+  let throttling = false;
+
+  return (...args) => {
+    if(!throttling) {
+      throttling = true;
+      window.requestAnimationFrame( () => {
+        throttling = false;
+        return Reflect.apply(callback, context, args);
+      });
+    }
+  };
+};
+
+export default fullThrottle;
diff --git a/node_modules/mdl-ext/src/utils/index.js b/node_modules/mdl-ext/src/utils/index.js
new file mode 100644
index 0000000..c04972d
--- /dev/null
+++ b/node_modules/mdl-ext/src/utils/index.js
@@ -0,0 +1,7 @@
+import './constants';
+import './dom-utils';
+import './string-utils';
+import './json-utils';
+import './full-throttle';
+import './easing';
+import './interval-function';
diff --git a/node_modules/mdl-ext/src/utils/interval-function.js b/node_modules/mdl-ext/src/utils/interval-function.js
new file mode 100644
index 0000000..4c344e3
--- /dev/null
+++ b/node_modules/mdl-ext/src/utils/interval-function.js
@@ -0,0 +1,83 @@
+const MIN_INERVAL = 1000/60;
+
+/**
+ * Trigger a callback at a given interval
+ * @param interval defaults to 1000/60 ms
+ * @return {function()} reference to start, stop, immediate and started
+ */
+
+const intervalFunction = ( interval = MIN_INERVAL ) => {
+
+  let lapse = interval < MIN_INERVAL ? MIN_INERVAL : interval;
+  let cb = undefined;
+  let next = null;
+  let timeElapsed = 0;
+
+  const execute = () => {
+    const f = cb(timeElapsed);
+    if (!f) {
+      cancel();
+    }
+  };
+
+  const cancel = () => {
+    if(next) {
+      window.cancelAnimationFrame(next);
+    }
+    next = null;
+    timeElapsed = 0;
+  };
+
+  const start = () => {
+    let timeStart = Date.now();
+
+    const loop = now => {
+      if (next) {
+        next = window.requestAnimationFrame( () => loop( Date.now() ));
+
+        timeElapsed += now - timeStart;
+
+        if(timeElapsed >= lapse) {
+          execute();
+          if( (timeElapsed -= lapse) > lapse) {
+            // time elapsed - interval_ > interval_ , indicates inactivity
+            // Could be due to browser minimized, tab changed, screen saver started, computer sleep, and so on
+            timeElapsed = 0;
+          }
+        }
+        timeStart = now;
+      }
+    };
+
+    next = 1;  // a truthy value for first loop
+    loop( timeStart );
+  };
+
+  return {
+    get started() {
+      return next != null;
+    },
+    get interval() {
+      return lapse;
+    },
+    set interval(value) {
+      lapse = value < MIN_INERVAL ? MIN_INERVAL : value;
+    },
+    start(callback) {
+      if(typeof callback !== 'function') {
+        throw new TypeError('callback parameter must be a function');
+      }
+      cb = callback;
+      start();
+    },
+    immediate() {
+      if(!cb) {
+        throw new ReferenceError('callback parameter is not defined. Call start before immediate.');
+      }
+      execute();
+    },
+    stop: () => cancel(),
+  };
+};
+
+export default intervalFunction;
diff --git a/node_modules/mdl-ext/src/utils/json-utils.js b/node_modules/mdl-ext/src/utils/json-utils.js
new file mode 100644
index 0000000..c6f6c77
--- /dev/null
+++ b/node_modules/mdl-ext/src/utils/json-utils.js
@@ -0,0 +1,18 @@
+'use strict';
+
+/**
+ * Converts a JSON string to object
+ * @param jsonString
+ * @param source
+ */
+const jsonStringToObject = (jsonString, source = {} ) => {
+  const s = jsonString.replace(/'/g, '"');
+  try {
+    return Object.assign(source, JSON.parse(s));
+  }
+  catch (e) {
+    throw new Error(`Failed to parse json string: ${s}. Error: ${e.message}`);
+  }
+};
+
+export { jsonStringToObject };
diff --git a/node_modules/mdl-ext/src/utils/resize-observer.js b/node_modules/mdl-ext/src/utils/resize-observer.js
new file mode 100644
index 0000000..b69e2f2
--- /dev/null
+++ b/node_modules/mdl-ext/src/utils/resize-observer.js
@@ -0,0 +1,294 @@
+
+/**
+ * An API for observing changes to Element’s size.
+ *
+ * @See https://wicg.github.io/ResizeObserver/
+ * @ee https://github.com/pelotoncycle/resize-observer
+ *
+ */
+
+import intervalFunction from './interval-function';
+
+((window, document) => {
+  'use strict';
+
+  if (typeof window.ResizeObserver !== 'undefined') {
+    return;
+  }
+
+  document.resizeObservers = [];
+
+  /**
+   * The content rect is defined in section 2.3 ResizeObserverEntry of the spec
+   * @param target the element to calculate the content rect for
+   * @return {{top: (Number|number), left: (Number|number), width: number, height: number}}
+   *
+   * Note:
+   * Avoid using margins on the observed element. The calculation can return incorrect values when margins are involved.
+   *
+   * The following CSS will report incorrect width (Chrome OSX):
+   *
+   * <div id="outer" style="width: 300px; height:300px; background-color: green;overflow:auto;">
+   *   <div id="observed" style="width: 400px; height:400px; background-color: yellow; margin:30px; border: 20px solid red; padding:10px;">
+   *   </div>
+   * </div>
+   *
+   * The calculated width is 280. The actual (correct) width is 340 since Chrome clips the margin.
+   *
+   * Use an outer container if you really need a "margin":
+   *
+   * <div id="outer" style="width: 300px; height:300px; background-color: green;overflow:auto; padding:30px;">
+   *   <div id="observed" style="width: 400px; height:400px; background-color: yellow; margin: 0; border: 20px solid red; padding:10px;">
+   *   </div>
+   * </div>
+   *
+   * A more detailed explanation can be fund here:
+   * http://stackoverflow.com/questions/21064101/understanding-offsetwidth-clientwidth-scrollwidth-and-height-respectively
+   */
+  const getContentRect = target => {
+    const cs = window.getComputedStyle(target);
+    const r = target.getBoundingClientRect();
+    const top = parseFloat(cs.paddingTop) || 0;
+    const left = parseFloat(cs.paddingLeft) || 0;
+    const width = r.width  - (
+        (parseFloat(cs.marginLeft) || 0) +
+        (parseFloat(cs.marginRight) || 0) +
+        (parseFloat(cs.borderLeftWidth) || 0) +
+        (parseFloat(cs.borderRightWidth) || 0) +
+        (left) +
+        (parseFloat(cs.paddingRight) || 0)
+      );
+    const height = r.height  - (
+        (parseFloat(cs.marginTop) || 0) +
+        (parseFloat(cs.marginBottom) || 0) +
+        (parseFloat(cs.borderTopWidth) || 0) +
+        (parseFloat(cs.borderBottomWidth) || 0) +
+        (top) +
+        (parseFloat(cs.paddingBottom) || 0)
+      );
+    return {width: width, height: height, top: top, left: left};
+  };
+
+  const dimensionHasChanged = (target, lastWidth, lastHeight) => {
+    const {width, height} = getContentRect(target);
+    return width !== lastWidth || height !== lastHeight;
+  };
+
+
+  /**
+   * ResizeObservation holds observation information for a single Element.
+   * @param target
+   * @return {{target: *, broadcastWidth, broadcastHeight, isOrphan: (function()), isActive: (function())}}
+   * @constructor
+   */
+  const ResizeObservation = target => {
+    const {width, height} = getContentRect(target);
+
+    return {
+      target: target,
+      broadcastWidth: width,
+      broadcastHeight: height,
+
+      isOrphan() {
+        return !this.target || !this.target.parentNode;
+      },
+      isActive() {
+        return dimensionHasChanged(this.target, this.broadcastWidth, this.broadcastHeight);
+      }
+    };
+  };
+
+  /**
+   * A snapshot of the observed element
+   * @param target
+   * @param rect
+   * @return {{target: *, contentRect: *}}
+   * @constructor
+   */
+  const ResizeObserverEntry = (target, rect) => {
+    return {
+      target: target,
+      contentRect: rect
+    };
+  };
+
+
+  /**
+   * The ResizeObserver is used to observe changes to Element's content rect.
+   */
+  class ResizeObserver {
+
+    /**
+     * Constructor for instantiating new Resize observers.
+     * @param callback void (sequence<ResizeObserverEntry> entries). The function which will be called on each resize.
+     * @throws {TypeError}
+     */
+    constructor( callback ) {
+
+      if(typeof callback !== 'function') {
+        throw new TypeError('callback parameter must be a function');
+      }
+
+      this.callback_ = callback;
+      this.observationTargets_ = [];
+      this.activeTargets_ = [];
+
+      document.resizeObservers.push(this);
+    }
+
+    /**
+     * A list of ResizeObservations. It represents all Elements being observed.
+     *
+     * @return {Array}
+     */
+    get observationTargets() {
+      return this.observationTargets_;
+    }
+
+    /**
+     *  A list of ResizeObservations. It represents all Elements whose size has
+     *  changed since last observation broadcast that are eligible for broadcast.
+     *
+     * @return {Array}
+     */
+    get activeTargets() {
+      return this.activeTargets_;
+    }
+
+    /**
+     * Adds target to the list of observed elements.
+     * @param {HTMLElement} target The target to observe
+     */
+    observe(target) {
+      if(target) {
+        if (!(target instanceof HTMLElement)) {
+          throw new TypeError('target parameter must be an HTMLElement');
+        }
+        if (!this.observationTargets_.find(t => t.target === target)) {
+          this.observationTargets_.push(ResizeObservation(target));
+          resizeController.start();
+        }
+      }
+    }
+
+    /**
+     * Removes target from the list of observed elements.
+     * @param target The target to remove
+     */
+    unobserve(target) {
+      const i = this.observationTargets_.findIndex(t => t.target === target);
+      if(i > -1) {
+        this.observationTargets_.splice(i, 1);
+      }
+    }
+
+    /**
+     * Stops the ResizeObserver instance from receiving notifications of resize changes.
+     * Until the observe() method is used again, observer's callback will not be invoked.
+     */
+    disconnect() {
+      this.observationTargets_ = [];
+      this.activeTargets_ = [];
+    }
+
+    /**
+     * Removes the ResizeObserver from the list of observers
+     */
+    destroy() {
+      this.disconnect();
+      const i = document.resizeObservers.findIndex(o => o === this);
+      if(i > -1) {
+        document.resizeObservers.splice(i, 1);
+      }
+    }
+
+    deleteOrphansAndPopulateActiveTargets_() {
+
+      // Works, but two iterations
+      //this.observationTargets_ = this.observationTargets_.filter( resizeObervation => !resizeObervation.isOrphan());
+      //this.activeTargets_ = this.observationTargets_.filter( resizeObervation => resizeObervation.isActive());
+
+      // Same result as above, one iteration
+      /*
+      this.activeTargets_ = [];
+      let n = this.observationTargets_.length-1;
+      while(n >= 0) {
+        if(this.observationTargets_[n].isOrphan()) {
+          this.observationTargets_.splice(n, 1);
+        }
+        else if(this.observationTargets_[n].isActive()) {
+          this.activeTargets_.push(this.observationTargets_[n]);
+        }
+        n -= 1;
+      }
+      */
+
+      // Same result as above - but reduce is cooler :-)
+      this.activeTargets_ = this.observationTargets_.reduceRight( (prev, resizeObservation, index, arr) => {
+        if(resizeObservation.isOrphan()) {
+          arr.splice(index, 1);
+        }
+        else if(resizeObservation.isActive()) {
+          prev.push(resizeObservation);
+        }
+        return prev;
+      }, []);
+    }
+
+    broadcast_() {
+      this.deleteOrphansAndPopulateActiveTargets_();
+      if (this.activeTargets_.length > 0) {
+        const entries = [];
+        for (const resizeObservation of this.activeTargets_) {
+          const rect = getContentRect(resizeObservation.target);
+          resizeObservation.broadcastWidth = rect.width;
+          resizeObservation.broadcastHeight = rect.height;
+          entries.push(ResizeObserverEntry(resizeObservation.target, rect));
+        }
+        this.callback_(entries);
+        this.activeTargets_ = [];
+      }
+    }
+  }
+
+
+  //let interval = require('./interval-function');
+
+  /**
+   * Broadcasts Element.resize events
+   * @return {{start: (function()), stop: (function())}}
+   * @constructor
+   */
+  const ResizeController = () => {
+
+    const shouldStop = () => {
+      return document.resizeObservers.findIndex( resizeObserver => resizeObserver.observationTargets.length > 0 ) > -1;
+    };
+
+    const execute = () => {
+      //console.log('***** Execute');
+      for(const resizeObserver of document.resizeObservers) {
+        resizeObserver.broadcast_();
+      }
+
+      return shouldStop();
+    };
+
+    const interval = intervalFunction(200);
+
+    return {
+      start() {
+        if(!interval.started) {
+          //console.log('***** Start poll');
+          interval.start(execute);
+        }
+      }
+    };
+  };
+
+  window.ResizeObserver = ResizeObserver;
+
+  const resizeController = ResizeController();
+  //console.log('***** ResizeObserver ready');
+
+})(window, document);
diff --git a/node_modules/mdl-ext/src/utils/snippets/resize-observer.html b/node_modules/mdl-ext/src/utils/snippets/resize-observer.html
new file mode 100644
index 0000000..5d956c2
--- /dev/null
+++ b/node_modules/mdl-ext/src/utils/snippets/resize-observer.html
@@ -0,0 +1,221 @@
+<!-- See: https://github.com/WICG/ResizeObserver/blob/master/demo.html -->
+
+<style>
+  .resize {
+    border: 2em solid rgba(0,255,0, 0.5);
+    background-color: #DDD;
+    width: 90%; //300.49px;
+    height: 200.5px;
+    overflow: hidden;
+    position:relative;
+    display:inline-block;
+  }
+  .yellowBorder {
+    border-width: 1px;
+    border-style: solid;
+  }
+
+  .maptiles {
+    overflow: hidden;
+  }
+
+  .maptiles::after {
+    content: "map tiles";
+    position: relative;
+    top: 20px;
+  }
+
+  .elipse {
+    border: 20px solid rgba(100,255,100, 0.5);
+  }
+  .elipse::after {
+    content: "canvas";
+    position: relative;
+    top: -100px;
+  }
+  .domMunch {
+    background-color: orange;
+  }
+  .domMunch > div {
+    display: inline-block;
+    width: 20px;
+    height: 20px;
+    border: 1px solid black;
+  }
+  .domMunch::after {
+    content: "domMunch";
+    position: relative;
+    top: 20px;
+  }
+
+  .toolbar {
+    margin: 16px 0;
+    position: relative;
+    display: flex;
+    align-items: center;
+  }
+
+  .toolbar > * {
+    margin-right: 8px;
+    min-width: 110px;
+    width: auto;
+  }
+
+  .toolbar > span {
+    flex-grow: 1;
+    text-align: right;
+    font-weight: 600;
+    font-size: 1.2em;
+  }
+</style>
+
+<h1 style="display:none">ResizeObserver unexpected error</h1>
+<pre id="log" style="display:none">log:</pre>
+
+<section class="toolbar">
+  <label class="mdl-checkbox mdl-js-checkbox mdl-js-ripple-effect">
+    <input id="cb-observe" type="checkbox" class="mdl-checkbox__input" checked>
+    <span class="mdl-checkbox__label">Observe</span>
+  </label>
+
+  <div id="input-inc-container" class="mdl-textfield mdl-textfield--floating-label mdl-js-textfield">
+    <input id="input-inc" class="mdl-textfield__input" type="number" min="1" max="40" value="10">
+    <label class="mdl-textfield__label">Size increment</label>
+  </div>
+
+  <button id="btn-grow" class="cmd-button mdl-button mdl-js-button mdl-button--raised">Grow</button>
+  <button id="btn-shrink" class="cmd-button mdl-button mdl-js-button mdl-button--raised">Shrink</button>
+  <button id="btn-delete" class="cmd-button mdl-button mdl-js-button mdl-button--raised">Delete observed element</button>
+
+  <span id="observe-notification">
+  </span>
+</section>
+
+
+<div id="observed-element" class="resize maptiles" ></div>
+
+<script>
+  'use strict';
+
+  (function() {
+    'use strict';
+    document.addEventListener('DOMContentLoaded', function() {
+
+      if (!window.ResizeObserver) {
+        throw new Error('no window.ResizeObserver');
+      }
+
+      function log(msg) {
+        var e = document.querySelector('#log');
+        e.textContent = e.innerText + '\n' + msg;
+      }
+
+      function nextColor() {
+        return '#'+Math.random().toString(16).substr(-6);
+      }
+
+      function grow() {
+        var inc = parseInt(document.querySelector('#input-inc').value);
+        var elements = document.querySelectorAll('.resize');
+        for (var i = 0; i < elements.length; i++) {
+          var el = elements[i];
+          var s = window.getComputedStyle(el);
+          var w = parseFloat(s.width);
+          var h = parseFloat(s.height);
+          el.style.width = (w + inc) + 'px';
+          el.style.height = (h + inc * 2 / 3) + 'px';
+        }
+      }
+
+      function shrink() {
+        var dec = parseInt(document.querySelector('#input-inc').value);
+        var elements = document.querySelectorAll('.resize');
+        for (var i = 0; i < elements.length; i++) {
+          var el = elements[i];
+          var s = window.getComputedStyle(el);
+          var w = parseFloat(s.width);
+          var h = parseFloat(s.height);
+          el.style.width = (w - dec) + 'px';
+          el.style.height = (h - dec * 2 / 3) + 'px';
+        }
+      }
+
+
+      function initResizeHandlers() {
+        var elements = document.querySelectorAll('.maptiles');
+        for (var i = 0; i < elements.length; i++) {
+          elements[i].onresize = function() { this.style.borderColor = nextColor() };
+        }
+      }
+
+      function displayNotification(value) {
+        var notification = document.querySelector("#observe-notification");
+        notification.style.color = nextColor();
+        if(Number.isInteger(value)) {
+          notification.innerHTML = '<span>Observed: ' + value + ' element' + (value > 1 ? 's' : '') + '</span>';
+        }
+        else {
+          notification.innerHTML = '<span>Observer: ' + value + '</span>';
+        }
+      }
+
+      //
+      // Init
+      //
+      window.addEventListener('error', function (e) {
+        var error = e.error;
+        console.log(error);
+        log(error);
+      });
+
+
+      var ro = new ResizeObserver( function(entries) {
+
+        displayNotification(entries.length);
+
+        for (var i = 0; i < entries.length; i++) {
+          var entry = entries[i];
+          if (!entry.target || !entry.target.parentNode) {
+            throw new Error("detected resize on orphan element");
+          }
+          if (entry.target.onresize) {
+            entry.target.onresize(entry);
+          }
+        }
+      });
+
+      function toggleObserve() {
+        var isObserve = document.querySelector('#cb-observe').checked;
+        displayNotification(isObserve ? 'on' : 'off');
+
+        var elements = document.querySelectorAll('.resize');
+        if (isObserve) {
+          for (var i = 0; i < elements.length; i++) {
+            ro.observe(elements[i]);
+          }
+        }
+        else {
+          for (var i = 0; i < elements.length; i++) {
+            ro.unobserve(elements[i]);
+          }
+        }
+      }
+
+      function deleteObservedElement() {
+        var el = document.querySelector('#observed-element');
+        el.parentNode.removeChild(el);
+      }
+
+
+      document.querySelector('#cb-observe').addEventListener('click', function() { toggleObserve() });
+      document.querySelector('#btn-grow').addEventListener('click', function() { grow() });
+      document.querySelector('#btn-shrink').addEventListener('click', function() { shrink() });
+      document.querySelector('#btn-delete').addEventListener('click', function() { deleteObservedElement() });
+
+      // Start
+      initResizeHandlers()
+      toggleObserve();
+    });
+
+  }());
+</script>
diff --git a/node_modules/mdl-ext/src/utils/string-utils.js b/node_modules/mdl-ext/src/utils/string-utils.js
new file mode 100644
index 0000000..38830cc
--- /dev/null
+++ b/node_modules/mdl-ext/src/utils/string-utils.js
@@ -0,0 +1,76 @@
+'use strict';
+
+/**
+ * @license
+ * Copyright 2016 Leif Olsen. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * A javascript utility for conditionally creating a list of strings.
+ * The function takes any number of arguments which can be a string or object.
+ * Inspired by (but not copied from) JedWatson/classnames, https://github.com/JedWatson/classnames
+ *
+ * @param  {*} args the strings and/or objects to
+ * @return {Array} a list of strings
+ * @example
+ * // Returns ['foo', 'bar', 'baz', 'quux']
+ * stringList(', ', 'foo', { bar: true, duck: false }, 'baz', { quux: true });
+ * @example see the tests for more examples
+ */
+const stringList = (...args) => {
+
+  const isString = str => str != null && typeof str === 'string';
+
+  const flatten = list => list.reduce((a, b) => a.concat(Array.isArray(b) ? flatten(b) : b), []);
+
+  const objectToStrings = arg =>
+    Object.keys(arg)
+      .filter(key => arg[key])
+      .map(key => key);
+
+  return args
+    .filter(arg => !!arg)
+    .map(arg => isString(arg) ? arg : objectToStrings(arg))
+    .reduce((result, arg) => result.concat(Array.isArray(arg) ? flatten(arg) : arg), []);
+};
+
+/**
+ * A simple javascript utility for conditionally joining strings together.
+ * The function takes a delimiter string and any number of arguments which can be a string or object.
+ *
+ * @param delimiter delimiter to separate joined strings
+ * @param  {*} args the strings and/or objects to join
+ * @return {String} the joined strings
+ * @example
+ * // Returns 'foo, bar, baz, quux'
+ * joinStrings(', ', 'foo', { bar: true, duck: false }, 'baz', { quux: true });
+ * @example see the tests for more examples
+ */
+const joinStrings = (delimiter = ' ', ...args) => stringList(...args).join(delimiter);
+
+/**
+ * Generates a random string with a given length
+ * @param n {Integer} length of generated string
+ * @see http://stackoverflow.com/questions/1349404/generate-random-string-characters-in-javascript
+ * @return {String} the random string
+ * @example
+ * // Returns e.g. 'pd781w0y'
+ * randomString(8);
+ * @example see the tests for more examples
+ */
+const randomString = ( n=12 ) => Array( n+1 ).join((`${Math.random().toString(36)}00000000000000000`).slice(2, 18)).slice(0, n);
+
+export { joinStrings, randomString, stringList };
+
diff --git a/node_modules/mdl-ext/src/utils/throttle-function.js b/node_modules/mdl-ext/src/utils/throttle-function.js
new file mode 100644
index 0000000..f236ec3
--- /dev/null
+++ b/node_modules/mdl-ext/src/utils/throttle-function.js
@@ -0,0 +1,61 @@
+/**
+ * Throttling enforces a maximum number of times a function can be called over time.
+ *
+ * @param callback the function to throttle
+ * @param delay optional delay, default to 1000/60ms
+ * @param context optional context of this, default to global window
+ * @returns {Function} reference to immediate and cancel functions
+ * @see https://developer.mozilla.org/en-US/docs/Web/Events/resize#Example
+ * @see https://gist.github.com/yoavniran/d1d33f278bb7744d55c3
+ * @see https://github.com/pelotoncycle/frame-throttle
+ * @see https://github.com/jeromedecoster/raf-funcs
+ */
+const MIN_DELAY = 1000/60;
+
+const throttleFunction = (callback, delay=MIN_DELAY, context) => {
+
+  if(delay < MIN_DELAY) {
+    delay = MIN_DELAY;
+  }
+
+  if (!context) {
+    context = this || window;
+  }
+
+  let next = null;
+  let start = 0;
+
+  return (...args) => {
+
+    const cancel = () => {
+      if(next !== null) {
+        window.cancelAnimationFrame(next);
+        next = null;
+      }
+    };
+
+    const execute = () => {
+      cancel();
+      return Reflect.apply(callback, context, args);
+    };
+
+    const later = () => {
+      if (delay - (Date.now() - start) <= 0) {
+        return execute();
+      }
+      next = window.requestAnimationFrame(later);
+    };
+
+    if(next === null) {
+      start = Date.now();
+      next = window.requestAnimationFrame(later);
+    }
+
+    return {
+      cancel: () => cancel(),
+      immediate: () => execute()
+    };
+  };
+};
+
+export default throttleFunction;