diff --git a/assets/css/app.scss b/assets/css/app.scss
index 7cb79ef..6b9d956 100644
--- a/assets/css/app.scss
+++ b/assets/css/app.scss
@@ -1,120 +1,22 @@
/* This file is for your main application css. */
-@import './phoenix.css';
-@import '../node_modules/nprogress/nprogress.css';
+@import "./fontawesome.scss";
+@import "./lato.scss";
-/* LiveView specific classes for your customizations */
-.invalid-feedback {
- color: #a94442;
- display: block;
- margin: -1rem 0 2rem;
-}
-
-.phx-no-feedback.invalid-feedback,
-.phx-no-feedback .invalid-feedback {
- display: none;
-}
-
-.phx-click-loading {
- opacity: 0.5;
- transition: opacity 1s ease-out;
-}
-
-.phx-disconnected {
- cursor: wait;
-}
-.phx-disconnected * {
- pointer-events: none;
-}
-
-.phx-modal {
- opacity: 1 !important;
- position: fixed;
- z-index: 1;
- left: 0;
- top: 0;
- width: 100%;
- height: 100%;
- overflow: auto;
- background-color: rgb(0, 0, 0);
- background-color: rgba(0, 0, 0, 0.4);
-}
-
-.phx-modal-content {
- background-color: #fefefe;
- margin: 15% auto;
- padding: 20px;
- border: 1px solid #888;
- width: 80%;
-}
-
-.phx-modal-close {
- color: #aaa;
- float: right;
- font-size: 28px;
- font-weight: bold;
-}
-
-.phx-modal-close:hover,
-.phx-modal-close:focus {
- color: black;
- text-decoration: none;
- cursor: pointer;
-}
+@import "tailwindcss/base";
+@import "tailwindcss/components";
+@import "tailwindcss/utilities";
-/* Alerts and form errors */
-.alert {
- padding: 15px;
- margin-bottom: 20px;
- border: 1px solid transparent;
- border-radius: 4px;
-}
-.alert-info {
- color: #31708f;
- background-color: #d9edf7;
- border-color: #bce8f1;
-}
-.alert-warning {
- color: #8a6d3b;
- background-color: #fcf8e3;
- border-color: #faebcc;
-}
-.alert-danger {
- color: #a94442;
- background-color: #f2dede;
- border-color: #ebccd1;
-}
-.alert p {
- margin-bottom: 0;
-}
-.alert:empty {
- display: none;
-}
+@import "../node_modules/nprogress/nprogress.css";
-// my styles
-
-.container {
- max-width: 120rem;
- color: white;
-}
+@import "./button.scss";
+@import "./live_view.scss";
+@import "./keypad.scss";
+@import "./select.scss";
+@import "./slider.scss";
body {
- background-color: #222;
-}
-
-div.screen {
- position: relative;
- top: 25px;
- left: 25px;
- height: 325px;
-}
-
-span.key,
-span.led {
- display: inline-block;
- position: absolute;
- border: 1px solid #222;
-}
-
-span.led {
- border-radius: 25px;
+ @apply text-white font-light bg-gray-900;
+ @apply mx-8;
+ font-family: lato, sans-serif;
+ font-size: 1.375rem;
}
diff --git a/assets/css/button.scss b/assets/css/button.scss
new file mode 100644
index 0000000..42ea036
--- /dev/null
+++ b/assets/css/button.scss
@@ -0,0 +1,15 @@
+button {
+ @apply text-lg bg-blue-800 text-white font-normal pt-2 pb-1 px-4 rounded;
+
+ .svg-inline--fa {
+ @apply text-base;
+ }
+
+ &:hover {
+ @apply bg-blue-600;
+ }
+
+ &:focus {
+ @apply outline-none;
+ }
+}
diff --git a/assets/css/fontawesome.scss b/assets/css/fontawesome.scss
new file mode 100644
index 0000000..d306d09
--- /dev/null
+++ b/assets/css/fontawesome.scss
@@ -0,0 +1,11 @@
+/*!
+ * Font Awesome Free 5.14.0 by @fontawesome - https://fontawesome.com
+ * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
+ */
+@font-face {
+ font-family: 'Font Awesome 5 Free';
+ font-style: normal;
+ font-weight: 900;
+ font-display: block;
+ src: url("/fonts/fa-solid-900.woff2") format("woff2"), url("/fonts/fa-solid-900.woff") format("woff");
+}
diff --git a/assets/css/keypad.scss b/assets/css/keypad.scss
new file mode 100644
index 0000000..ef610ad
--- /dev/null
+++ b/assets/css/keypad.scss
@@ -0,0 +1,32 @@
+.keypad {
+ @apply relative;
+
+ .frame {
+ @apply relative;
+ @apply border border-gray-700 border-solid;
+ border-radius: .625rem;
+ width: 250px;
+ height: 320px;
+ top: -53px;
+ left: -53px;
+ }
+}
+
+.key,
+.led {
+ display: inline-block;
+ position: absolute;
+}
+
+.key {
+ border-radius: 6px;
+ box-shadow: inset 0 -1px 0 3px rgba(0, 0, 0, 0.1), 0 0 0 1px rgba(0, 0, 0, 0.3);
+ border-left: 1px solid rgba(0, 0, 0, 0.1);
+ border-right: 1px solid rgba(0, 0, 0, 0.1);
+
+ padding-top: 6px;
+}
+
+.led {
+ border-radius: 25px;
+}
diff --git a/assets/css/lato.scss b/assets/css/lato.scss
new file mode 100644
index 0000000..3954dc1
--- /dev/null
+++ b/assets/css/lato.scss
@@ -0,0 +1,179 @@
+/*!
+ Lato font.
+*/
+/* Lato (hairline, regular) */
+/*
+@font-face {
+ font-family: Lato;
+ font-weight: 100;
+ font-style: normal;
+ text-rendering: optimizeLegibility;
+ src: url("/fonts/lato-hairline.woff2") format("woff2"), url("/fonts/lato-hairline.woff") format("woff");
+}
+*/
+/* Lato (hairline, italic) */
+/*
+@font-face {
+ font-family: Lato;
+ font-weight: 100;
+ font-style: italic;
+ text-rendering: optimizeLegibility;
+ src: url("/fonts/lato-hairline-italic.woff2") format("woff2"), url("/fonts/lato-hairline-italic.woff") format("woff");
+}
+*/
+/* Lato (thin, regular) */
+/*
+@font-face {
+ font-family: Lato;
+ font-weight: 200;
+ font-style: normal;
+ text-rendering: optimizeLegibility;
+ src: url("/fonts/lato-thin.woff2") format("woff2"), url("/fonts/lato-thin.woff") format("woff");
+}
+*/
+/* Lato (thin, italic) */
+/*
+@font-face {
+ font-family: Lato;
+ font-weight: 200;
+ font-style: italic;
+ text-rendering: optimizeLegibility;
+ src: url("/fonts/lato-thin-italic.woff2") format("woff2"), url("/fonts/lato-thin-italic.woff") format("woff");
+}
+*/
+/* Lato (light, regular) */
+@font-face {
+ font-family: Lato;
+ font-weight: 300;
+ font-style: normal;
+ text-rendering: optimizeLegibility;
+ src: url("/fonts/lato-light.woff2") format("woff2"), url("/fonts/lato-light.woff") format("woff");
+}
+/* Lato (light, italic) */
+/*
+@font-face {
+ font-family: Lato;
+ font-weight: 300;
+ font-style: italic;
+ text-rendering: optimizeLegibility;
+ src: url("/fonts/lato-light-italic.woff2") format("woff2"), url("/fonts/lato-light-italic.woff") format("woff");
+}
+*/
+/* Lato (normal, regular) */
+@font-face {
+ font-family: Lato;
+ font-weight: 400;
+ font-style: normal;
+ text-rendering: optimizeLegibility;
+ src: url("/fonts/lato-normal.woff2") format("woff2"), url("/fonts/lato-normal.woff") format("woff");
+}
+/* Lato (normal, italic) */
+/*
+@font-face {
+ font-family: Lato;
+ font-weight: 400;
+ font-style: italic;
+ text-rendering: optimizeLegibility;
+ src: url("/fonts/lato-normal-italic.woff2") format("woff2"), url("/fonts/lato-normal-italic.woff") format("woff");
+}
+*/
+/* Lato (medium, regular) */
+/*
+@font-face {
+ font-family: "Lato Medium";
+ font-weight: 400;
+ font-style: normal;
+ text-rendering: optimizeLegibility;
+ src: url("/fonts/lato-medium.woff2") format("woff2"), url("/fonts/lato-medium.woff") format("woff");
+}
+*/
+/* Lato (medium, italic) */
+/*
+@font-face {
+ font-family: "Lato Medium";
+ font-weight: 400;
+ font-style: italic;
+ text-rendering: optimizeLegibility;
+ src: url("/fonts/lato-medium-italic.woff2") format("woff2"), url("/fonts/lato-medium-italic.woff") format("woff");
+}
+*/
+/* Lato (semibold, regular) */
+/*
+@font-face {
+ font-family: Lato;
+ font-weight: 500;
+ font-style: normal;
+ text-rendering: optimizeLegibility;
+ src: url("/fonts/lato-semibold.woff2") format("woff2"), url("/fonts/lato-semibold.woff") format("woff");
+}
+*/
+/* Lato (semibold, italic) */
+/*
+@font-face {
+ font-family: Lato;
+ font-weight: 500;
+ font-style: italic;
+ text-rendering: optimizeLegibility;
+ src: url("/fonts/lato-semibold-italic.woff2") format("woff2"), url("/fonts/lato-semibold-italic.woff") format("woff");
+}
+*/
+/* Lato (bold, regular) */
+/*
+@font-face {
+ font-family: Lato;
+ font-weight: 600;
+ font-style: normal;
+ text-rendering: optimizeLegibility;
+ src: url("/fonts/lato-bold.woff2") format("woff2"), url("/fonts/lato-bold.woff") format("woff");
+}
+*/
+/* Lato (bold, italic) */
+/*
+@font-face {
+ font-family: Lato;
+ font-weight: 600;
+ font-style: italic;
+ text-rendering: optimizeLegibility;
+ src: url("/fonts/lato-bold-italic.woff2") format("woff2"), url("/fonts/lato-bold-italic.woff") format("woff");
+}
+*/
+/* Lato (heavy, regular) */
+/*
+@font-face {
+ font-family: Lato;
+ font-weight: 800;
+ font-style: normal;
+ text-rendering: optimizeLegibility;
+ src: url("/fonts/lato-heavy.woff2") format("woff2"), url("/fonts/lato-heavy.woff") format("woff");
+}
+*/
+/* Lato (heavy, italic) */
+/*
+@font-face {
+ font-family: Lato;
+ font-weight: 800;
+ font-style: italic;
+ text-rendering: optimizeLegibility;
+ src: url("/fonts/lato-heavy-italic.woff2") format("woff2"), url("/fonts/lato-heavy-italic.woff") format("woff");
+}
+*/
+/* Lato (black, regular) */
+/*
+@font-face {
+ font-family: Lato;
+ font-weight: 900;
+ font-style: normal;
+ text-rendering: optimizeLegibility;
+ src: url("/fonts/lato-black.woff2") format("woff2"), url("/fonts/lato-black.woff") format("woff");
+}
+*/
+/* Lato (black, italic) */
+/*
+@font-face {
+ font-family: Lato;
+ font-weight: 900;
+ font-style: italic;
+ text-rendering: optimizeLegibility;
+ src: url("/fonts/lato-black-italic.woff2") format("woff2"), url("/fonts/lato-black-italic.woff") format("woff");
+}
+*/
diff --git a/assets/css/live_view.scss b/assets/css/live_view.scss
new file mode 100644
index 0000000..dcbe3e0
--- /dev/null
+++ b/assets/css/live_view.scss
@@ -0,0 +1,87 @@
+/* LiveView specific classes for your customizations */
+.invalid-feedback {
+ color: #a94442;
+ display: block;
+ margin: -1rem 0 2rem;
+}
+
+.phx-no-feedback.invalid-feedback,
+.phx-no-feedback .invalid-feedback {
+ display: none;
+}
+
+.phx-click-loading {
+ opacity: 0.5;
+ transition: opacity 1s ease-out;
+}
+
+.phx-disconnected {
+ cursor: wait;
+}
+.phx-disconnected * {
+ pointer-events: none;
+}
+
+.phx-modal {
+ opacity: 1 !important;
+ position: fixed;
+ z-index: 1;
+ left: 0;
+ top: 0;
+ width: 100%;
+ height: 100%;
+ overflow: auto;
+ background-color: rgb(0, 0, 0);
+ background-color: rgba(0, 0, 0, 0.4);
+}
+
+.phx-modal-content {
+ background-color: #fefefe;
+ margin: 15% auto;
+ padding: 20px;
+ border: 1px solid #888;
+ width: 80%;
+}
+
+.phx-modal-close {
+ color: #aaa;
+ float: right;
+ font-size: 28px;
+ font-weight: bold;
+}
+
+.phx-modal-close:hover,
+.phx-modal-close:focus {
+ color: black;
+ text-decoration: none;
+ cursor: pointer;
+}
+
+/* Alerts and form errors */
+.alert {
+ padding: 15px;
+ margin-bottom: 20px;
+ border: 1px solid transparent;
+ border-radius: 4px;
+}
+.alert-info {
+ color: #31708f;
+ background-color: #d9edf7;
+ border-color: #bce8f1;
+}
+.alert-warning {
+ color: #8a6d3b;
+ background-color: #fcf8e3;
+ border-color: #faebcc;
+}
+.alert-danger {
+ color: #a94442;
+ background-color: #f2dede;
+ border-color: #ebccd1;
+}
+.alert p {
+ margin-bottom: 0;
+}
+.alert:empty {
+ display: none;
+}
diff --git a/assets/css/phoenix.css b/assets/css/phoenix.css
deleted file mode 100644
index 3767b31..0000000
--- a/assets/css/phoenix.css
+++ /dev/null
@@ -1,101 +0,0 @@
-/* Includes some default style for the starter application.
- * This can be safely deleted to start fresh.
- */
-
-/* Milligram v1.3.0 https://milligram.github.io
- * Copyright (c) 2017 CJ Patoilo Licensed under the MIT license
- */
-
-*,*:after,*:before{box-sizing:inherit}html{box-sizing:border-box;font-size:62.5%}body{color:#000000;font-family:'Helvetica', 'Arial', sans-serif;font-size:1.6em;font-weight:300;line-height:1.6}blockquote{border-left:0.3rem solid #d1d1d1;margin-left:0;margin-right:0;padding:1rem 1.5rem}blockquote *:last-child{margin-bottom:0}.button,button,input[type='button'],input[type='reset'],input[type='submit']{background-color:#0069d9;border:0.1rem solid #0069d9;border-radius:.4rem;color:#fff;cursor:pointer;display:inline-block;font-size:1.1rem;font-weight:700;height:3.8rem;letter-spacing:.1rem;line-height:3.8rem;padding:0 3.0rem;text-align:center;text-decoration:none;text-transform:uppercase;white-space:nowrap}.button:focus,.button:hover,button:focus,button:hover,input[type='button']:focus,input[type='button']:hover,input[type='reset']:focus,input[type='reset']:hover,input[type='submit']:focus,input[type='submit']:hover{background-color:#606c76;border-color:#606c76;color:#fff;outline:0}.button[disabled],button[disabled],input[type='button'][disabled],input[type='reset'][disabled],input[type='submit'][disabled]{cursor:default;opacity:.5}.button[disabled]:focus,.button[disabled]:hover,button[disabled]:focus,button[disabled]:hover,input[type='button'][disabled]:focus,input[type='button'][disabled]:hover,input[type='reset'][disabled]:focus,input[type='reset'][disabled]:hover,input[type='submit'][disabled]:focus,input[type='submit'][disabled]:hover{background-color:#0069d9;border-color:#0069d9}.button.button-outline,button.button-outline,input[type='button'].button-outline,input[type='reset'].button-outline,input[type='submit'].button-outline{background-color:transparent;color:#0069d9}.button.button-outline:focus,.button.button-outline:hover,button.button-outline:focus,button.button-outline:hover,input[type='button'].button-outline:focus,input[type='button'].button-outline:hover,input[type='reset'].button-outline:focus,input[type='reset'].button-outline:hover,input[type='submit'].button-outline:focus,input[type='submit'].button-outline:hover{background-color:transparent;border-color:#606c76;color:#606c76}.button.button-outline[disabled]:focus,.button.button-outline[disabled]:hover,button.button-outline[disabled]:focus,button.button-outline[disabled]:hover,input[type='button'].button-outline[disabled]:focus,input[type='button'].button-outline[disabled]:hover,input[type='reset'].button-outline[disabled]:focus,input[type='reset'].button-outline[disabled]:hover,input[type='submit'].button-outline[disabled]:focus,input[type='submit'].button-outline[disabled]:hover{border-color:inherit;color:#0069d9}.button.button-clear,button.button-clear,input[type='button'].button-clear,input[type='reset'].button-clear,input[type='submit'].button-clear{background-color:transparent;border-color:transparent;color:#0069d9}.button.button-clear:focus,.button.button-clear:hover,button.button-clear:focus,button.button-clear:hover,input[type='button'].button-clear:focus,input[type='button'].button-clear:hover,input[type='reset'].button-clear:focus,input[type='reset'].button-clear:hover,input[type='submit'].button-clear:focus,input[type='submit'].button-clear:hover{background-color:transparent;border-color:transparent;color:#606c76}.button.button-clear[disabled]:focus,.button.button-clear[disabled]:hover,button.button-clear[disabled]:focus,button.button-clear[disabled]:hover,input[type='button'].button-clear[disabled]:focus,input[type='button'].button-clear[disabled]:hover,input[type='reset'].button-clear[disabled]:focus,input[type='reset'].button-clear[disabled]:hover,input[type='submit'].button-clear[disabled]:focus,input[type='submit'].button-clear[disabled]:hover{color:#0069d9}code{background:#f4f5f6;border-radius:.4rem;font-size:86%;margin:0 .2rem;padding:.2rem .5rem;white-space:nowrap}pre{background:#f4f5f6;border-left:0.3rem solid #0069d9;overflow-y:hidden}pre>code{border-radius:0;display:block;padding:1rem 1.5rem;white-space:pre}hr{border:0;border-top:0.1rem solid #f4f5f6;margin:3.0rem 0}input[type='email'],input[type='number'],input[type='password'],input[type='search'],input[type='tel'],input[type='text'],input[type='url'],textarea,select{-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:transparent;border:0.1rem solid #d1d1d1;border-radius:.4rem;box-shadow:none;box-sizing:inherit;height:3.8rem;padding:.6rem 1.0rem;width:100%}input[type='email']:focus,input[type='number']:focus,input[type='password']:focus,input[type='search']:focus,input[type='tel']:focus,input[type='text']:focus,input[type='url']:focus,textarea:focus,select:focus{border-color:#0069d9;outline:0}select{background:url('data:image/svg+xml;utf8,') center right no-repeat;padding-right:3.0rem}select:focus{background-image:url('data:image/svg+xml;utf8,')}textarea{min-height:6.5rem}label,legend{display:block;font-size:1.6rem;font-weight:700;margin-bottom:.5rem}fieldset{border-width:0;padding:0}input[type='checkbox'],input[type='radio']{display:inline}.label-inline{display:inline-block;font-weight:normal;margin-left:.5rem}.row{display:flex;flex-direction:column;padding:0;width:100%}.row.row-no-padding{padding:0}.row.row-no-padding>.column{padding:0}.row.row-wrap{flex-wrap:wrap}.row.row-top{align-items:flex-start}.row.row-bottom{align-items:flex-end}.row.row-center{align-items:center}.row.row-stretch{align-items:stretch}.row.row-baseline{align-items:baseline}.row .column{display:block;flex:1 1 auto;margin-left:0;max-width:100%;width:100%}.row .column.column-offset-10{margin-left:10%}.row .column.column-offset-20{margin-left:20%}.row .column.column-offset-25{margin-left:25%}.row .column.column-offset-33,.row .column.column-offset-34{margin-left:33.3333%}.row .column.column-offset-50{margin-left:50%}.row .column.column-offset-66,.row .column.column-offset-67{margin-left:66.6666%}.row .column.column-offset-75{margin-left:75%}.row .column.column-offset-80{margin-left:80%}.row .column.column-offset-90{margin-left:90%}.row .column.column-10{flex:0 0 10%;max-width:10%}.row .column.column-20{flex:0 0 20%;max-width:20%}.row .column.column-25{flex:0 0 25%;max-width:25%}.row .column.column-33,.row .column.column-34{flex:0 0 33.3333%;max-width:33.3333%}.row .column.column-40{flex:0 0 40%;max-width:40%}.row .column.column-50{flex:0 0 50%;max-width:50%}.row .column.column-60{flex:0 0 60%;max-width:60%}.row .column.column-66,.row .column.column-67{flex:0 0 66.6666%;max-width:66.6666%}.row .column.column-75{flex:0 0 75%;max-width:75%}.row .column.column-80{flex:0 0 80%;max-width:80%}.row .column.column-90{flex:0 0 90%;max-width:90%}.row .column .column-top{align-self:flex-start}.row .column .column-bottom{align-self:flex-end}.row .column .column-center{-ms-grid-row-align:center;align-self:center}@media (min-width: 40rem){.row{flex-direction:row;margin-left:-1.0rem;width:calc(100% + 2.0rem)}.row .column{margin-bottom:inherit;padding:0 1.0rem}}a{color:#0069d9;text-decoration:none}a:focus,a:hover{color:#606c76}dl,ol,ul{list-style:none;margin-top:0;padding-left:0}dl dl,dl ol,dl ul,ol dl,ol ol,ol ul,ul dl,ul ol,ul ul{font-size:90%;margin:1.5rem 0 1.5rem 3.0rem}ol{list-style:decimal inside}ul{list-style:circle inside}.button,button,dd,dt,li{margin-bottom:1.0rem}fieldset,input,select,textarea{margin-bottom:1.5rem}blockquote,dl,figure,form,ol,p,pre,table,ul{margin-bottom:2.5rem}table{border-spacing:0;width:100%}td,th{border-bottom:0.1rem solid #e1e1e1;padding:1.2rem 1.5rem;text-align:left}td:first-child,th:first-child{padding-left:0}td:last-child,th:last-child{padding-right:0}b,strong{font-weight:bold}p{margin-top:0}h1,h2,h3,h4,h5,h6{font-weight:300;letter-spacing:-.1rem;margin-bottom:2.0rem;margin-top:0}h1{font-size:4.6rem;line-height:1.2}h2{font-size:3.6rem;line-height:1.25}h3{font-size:2.8rem;line-height:1.3}h4{font-size:2.2rem;letter-spacing:-.08rem;line-height:1.35}h5{font-size:1.8rem;letter-spacing:-.05rem;line-height:1.5}h6{font-size:1.6rem;letter-spacing:0;line-height:1.4}img{max-width:100%}.clearfix:after{clear:both;content:' ';display:table}.float-left{float:left}.float-right{float:right}
-
-/* General style */
-h1{font-size: 3.6rem; line-height: 1.25}
-h2{font-size: 2.8rem; line-height: 1.3}
-h3{font-size: 2.2rem; letter-spacing: -.08rem; line-height: 1.35}
-h4{font-size: 1.8rem; letter-spacing: -.05rem; line-height: 1.5}
-h5{font-size: 1.6rem; letter-spacing: 0; line-height: 1.4}
-h6{font-size: 1.4rem; letter-spacing: 0; line-height: 1.2}
-pre{padding: 1em;}
-
-.container{
- margin: 0 auto;
- max-width: 80.0rem;
- padding: 0 2.0rem;
- position: relative;
- width: 100%
-}
-select {
- width: auto;
-}
-
-/* Phoenix promo and logo */
-.phx-hero {
- text-align: center;
- border-bottom: 1px solid #e3e3e3;
- background: #eee;
- border-radius: 6px;
- padding: 3em 3em 1em;
- margin-bottom: 3rem;
- font-weight: 200;
- font-size: 120%;
-}
-.phx-hero input {
- background: #ffffff;
-}
-.phx-logo {
- min-width: 300px;
- margin: 1rem;
- display: block;
-}
-.phx-logo img {
- width: auto;
- display: block;
-}
-
-/* Headers */
-header {
- width: 100%;
- background: #fdfdfd;
- border-bottom: 1px solid #eaeaea;
- margin-bottom: 2rem;
-}
-header section {
- align-items: center;
- display: flex;
- flex-direction: column;
- justify-content: space-between;
-}
-header section :first-child {
- order: 2;
-}
-header section :last-child {
- order: 1;
-}
-header nav ul,
-header nav li {
- margin: 0;
- padding: 0;
- display: block;
- text-align: right;
- white-space: nowrap;
-}
-header nav ul {
- margin: 1rem;
- margin-top: 0;
-}
-header nav a {
- display: block;
-}
-
-@media (min-width: 40.0rem) { /* Small devices (landscape phones, 576px and up) */
- header section {
- flex-direction: row;
- }
- header nav ul {
- margin: 1rem;
- }
- .phx-logo {
- flex-basis: 527px;
- margin: 2rem 1rem;
- }
-}
diff --git a/assets/css/select.scss b/assets/css/select.scss
new file mode 100644
index 0000000..42bba6d
--- /dev/null
+++ b/assets/css/select.scss
@@ -0,0 +1,26 @@
+.select-wrapper {
+ @apply relative;
+
+ &::after {
+ @apply absolute;
+ content: "\f078";
+ font-family: "Font Awesome 5 Free";
+ @apply text-xs;
+ top: .75rem;
+ right: .875rem;
+ @apply pointer-events-none;
+ }
+
+ select {
+ -webkit-appearance: none;
+ -moz-appearance: none;
+ appearance: none;
+
+ @apply text-lg bg-blue-800 text-white font-normal pt-2 pb-1 px-4 rounded w-full;
+ @apply cursor-pointer;
+
+ &:focus {
+ @apply outline-none;
+ }
+ }
+}
diff --git a/assets/css/slider.scss b/assets/css/slider.scss
new file mode 100644
index 0000000..d43ac66
--- /dev/null
+++ b/assets/css/slider.scss
@@ -0,0 +1,58 @@
+/* Reset styling in all browsers */
+
+input[type=range] {
+ -webkit-appearance: none;
+ @apply bg-transparent;
+
+ &::-webkit-slider-thumb {
+ -webkit-appearance: none;
+ }
+
+ &:focus {
+ @apply outline-none;
+ }
+}
+
+/* Apply custom styling */
+
+input[type=range] {
+ height: 22px;
+ @apply my-2;
+
+ &::-webkit-slider-thumb {
+ -webkit-appearance: none;
+ @apply bg-blue-100 rounded-full;
+ height: 22px;
+ width: 22px;
+ margin-top: -8px;
+ @apply cursor-pointer;
+ }
+
+ &::-moz-range-thumb {
+ @apply bg-blue-100 rounded-full border-none;
+ height: 22px;
+ width: 22px;
+ margin-top: -8px;
+ @apply cursor-pointer;
+ }
+
+ &::-webkit-slider-runnable-track {
+ @apply bg-blue-800 rounded-full;
+ height: 6px;
+ @apply cursor-pointer;
+ }
+
+ &:hover::-webkit-slider-runnable-track {
+ @apply bg-blue-600;
+ }
+
+ &::-moz-range-track {
+ @apply bg-blue-800 rounded-full;
+ height: 6px;
+ @apply cursor-pointer;
+ }
+
+ &:hover::-moz-range-track {
+ @apply bg-blue-600;
+ }
+}
diff --git a/assets/js/app.js b/assets/js/app.js
index 38a7104..282219b 100644
--- a/assets/js/app.js
+++ b/assets/js/app.js
@@ -1,3 +1,5 @@
+import "@fortawesome/fontawesome-free/js/all.min.js"
+
// We need to import the CSS so that webpack will load it.
// The MiniCssExtractPlugin is used to separate it out into
// its own CSS file.
diff --git a/assets/package-lock.json b/assets/package-lock.json
index 97f32a1..719af9b 100644
--- a/assets/package-lock.json
+++ b/assets/package-lock.json
@@ -1008,6 +1008,21 @@
}
}
},
+ "@fortawesome/fontawesome-free": {
+ "version": "5.14.0",
+ "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-free/-/fontawesome-free-5.14.0.tgz",
+ "integrity": "sha512-OfdMsF+ZQgdKHP9jUbmDcRrP0eX90XXrsXIdyjLbkmSBzmMXPABB8eobUJtivaupucYaByz6WNe1PI1JuYm3qA=="
+ },
+ "@fullhuman/postcss-purgecss": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/@fullhuman/postcss-purgecss/-/postcss-purgecss-2.3.0.tgz",
+ "integrity": "sha512-qnKm5dIOyPGJ70kPZ5jiz0I9foVOic0j+cOzNDoo8KoCf6HjicIZ99UfO2OmE7vCYSKAAepEwJtNzpiiZAh9xw==",
+ "dev": true,
+ "requires": {
+ "postcss": "7.0.32",
+ "purgecss": "^2.3.0"
+ }
+ },
"@nodelib/fs.scandir": {
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz",
@@ -1051,6 +1066,12 @@
}
}
},
+ "@types/color-name": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz",
+ "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==",
+ "dev": true
+ },
"@types/json-schema": {
"version": "7.0.4",
"resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.4.tgz",
@@ -1262,6 +1283,31 @@
"integrity": "sha512-ZVA9k326Nwrj3Cj9jlh3wGFutC2ZornPNARZwsNYqQYgN0EsV2d53w5RN/co65Ohn4sUAUtb1rSUAOD6XN9idA==",
"dev": true
},
+ "acorn-node": {
+ "version": "1.8.2",
+ "resolved": "https://registry.npmjs.org/acorn-node/-/acorn-node-1.8.2.tgz",
+ "integrity": "sha512-8mt+fslDufLYntIoPAaIMUe/lrbrehIiwmR3t2k9LljIzoigEPF27eLk2hy8zSGzmR/ogr7zbRKINMo1u0yh5A==",
+ "dev": true,
+ "requires": {
+ "acorn": "^7.0.0",
+ "acorn-walk": "^7.0.0",
+ "xtend": "^4.0.2"
+ },
+ "dependencies": {
+ "acorn": {
+ "version": "7.3.1",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.3.1.tgz",
+ "integrity": "sha512-tLc0wSnatxAQHVHUapaHdz72pi9KUyHjq5KyHjGg9Y8Ifdc79pTh2XvI6I1/chZbnM7QtNKzh66ooDogPZSleA==",
+ "dev": true
+ }
+ }
+ },
+ "acorn-walk": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz",
+ "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==",
+ "dev": true
+ },
"aggregate-error": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.0.1.tgz",
@@ -1495,6 +1541,29 @@
"integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==",
"dev": true
},
+ "autoprefixer": {
+ "version": "9.8.6",
+ "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.8.6.tgz",
+ "integrity": "sha512-XrvP4VVHdRBCdX1S3WXVD8+RyG9qeb1D5Sn1DeLiG2xfSpzellk5k54xbUERJ3M5DggQxes39UGOTP8CFrEGbg==",
+ "dev": true,
+ "requires": {
+ "browserslist": "^4.12.0",
+ "caniuse-lite": "^1.0.30001109",
+ "colorette": "^1.2.1",
+ "normalize-range": "^0.1.2",
+ "num2fraction": "^1.2.2",
+ "postcss": "^7.0.32",
+ "postcss-value-parser": "^4.1.0"
+ },
+ "dependencies": {
+ "caniuse-lite": {
+ "version": "1.0.30001109",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001109.tgz",
+ "integrity": "sha512-4JIXRodHzdS3HdK8nSgIqXYLExOvG+D2/EenSvcub2Kp3QEADjo2v2oUn5g0n0D+UNwG9BtwKOyGcSq2qvQXvQ==",
+ "dev": true
+ }
+ }
+ },
"aws-sign2": {
"version": "0.7.0",
"resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz",
@@ -1831,6 +1900,12 @@
"integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=",
"dev": true
},
+ "bytes": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz",
+ "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==",
+ "dev": true
+ },
"cacache": {
"version": "15.0.5",
"resolved": "https://registry.npmjs.org/cacache/-/cacache-15.0.5.tgz",
@@ -1934,6 +2009,12 @@
"integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
"dev": true
},
+ "camelcase-css": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz",
+ "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==",
+ "dev": true
+ },
"camelcase-keys": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz",
@@ -2204,6 +2285,12 @@
"simple-swizzle": "^0.2.2"
}
},
+ "colorette": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.1.tgz",
+ "integrity": "sha512-puCDz0CzydiSYOrnXpz/PKd69zRrribezjtE9yd4zvytoRc8+RY/KJPvtPFKZS3E3wP6neGyMe0vOTlHO5L3Pw==",
+ "dev": true
+ },
"combined-stream": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
@@ -2644,6 +2731,12 @@
}
}
},
+ "css-unit-converter": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/css-unit-converter/-/css-unit-converter-1.1.2.tgz",
+ "integrity": "sha512-IiJwMC8rdZE0+xiEZHeru6YoONC4rfPMqGm2W85jMIbkFvv5nFTwJVFHam2eFrN6txmoUYFAFXiv8ICVeTO0MA==",
+ "dev": true
+ },
"css-what": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/css-what/-/css-what-3.3.0.tgz",
@@ -2861,6 +2954,12 @@
}
}
},
+ "defined": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz",
+ "integrity": "sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=",
+ "dev": true
+ },
"delayed-stream": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
@@ -2889,6 +2988,17 @@
"integrity": "sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc=",
"dev": true
},
+ "detective": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/detective/-/detective-5.2.0.tgz",
+ "integrity": "sha512-6SsIx+nUUbuK0EthKjv0zrdnajCCXVYGmbYYiYjFVpzcjwEs/JMDZ8tPRG29J/HhN56t3GJp2cGSWDRjjot8Pg==",
+ "dev": true,
+ "requires": {
+ "acorn-node": "^1.6.1",
+ "defined": "^1.0.0",
+ "minimist": "^1.1.1"
+ }
+ },
"diffie-hellman": {
"version": "5.0.3",
"resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz",
@@ -3417,6 +3527,29 @@
"integrity": "sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw==",
"dev": true
},
+ "file-loader": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-6.0.0.tgz",
+ "integrity": "sha512-/aMOAYEFXDdjG0wytpTL5YQLfZnnTmLNjn+AIrJ/6HVnTfDqLsVKUUwkDf4I4kgex36BvjuXEn/TX9B/1ESyqQ==",
+ "dev": true,
+ "requires": {
+ "loader-utils": "^2.0.0",
+ "schema-utils": "^2.6.5"
+ },
+ "dependencies": {
+ "loader-utils": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz",
+ "integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==",
+ "dev": true,
+ "requires": {
+ "big.js": "^5.2.2",
+ "emojis-list": "^3.0.0",
+ "json5": "^2.1.2"
+ }
+ }
+ }
+ },
"fill-range": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz",
@@ -3524,6 +3657,17 @@
"readable-stream": "^2.0.0"
}
},
+ "fs-extra": {
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz",
+ "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "^4.2.0",
+ "jsonfile": "^4.0.0",
+ "universalify": "^0.1.0"
+ }
+ },
"fs-minipass": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz",
@@ -3947,6 +4091,15 @@
"integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==",
"dev": true
},
+ "import-cwd": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/import-cwd/-/import-cwd-2.1.0.tgz",
+ "integrity": "sha1-qmzzbnInYShcs3HsZRn1PiQ1sKk=",
+ "dev": true,
+ "requires": {
+ "import-from": "^2.1.0"
+ }
+ },
"import-fresh": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz",
@@ -3957,6 +4110,15 @@
"resolve-from": "^3.0.0"
}
},
+ "import-from": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/import-from/-/import-from-2.1.0.tgz",
+ "integrity": "sha1-M1238qev/VOqpHHUuAId7ja387E=",
+ "dev": true,
+ "requires": {
+ "resolve-from": "^3.0.0"
+ }
+ },
"import-local": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/import-local/-/import-local-2.0.0.tgz",
@@ -4408,6 +4570,15 @@
"minimist": "^1.2.5"
}
},
+ "jsonfile": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz",
+ "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "^4.1.6"
+ }
+ },
"jsprim": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz",
@@ -4442,6 +4613,12 @@
"webpack-sources": "^1.1.0"
}
},
+ "lato-font": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/lato-font/-/lato-font-3.0.0.tgz",
+ "integrity": "sha1-kbg34jdLZo+3Mx1EyJTTei2fjhE=",
+ "dev": true
+ },
"leven": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz",
@@ -4527,6 +4704,12 @@
"integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=",
"dev": true
},
+ "lodash.toarray": {
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/lodash.toarray/-/lodash.toarray-4.4.0.tgz",
+ "integrity": "sha1-JMS/zWsvuji/0FlNsRedjptlZWE=",
+ "dev": true
+ },
"lodash.uniq": {
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz",
@@ -4906,6 +5089,15 @@
"integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==",
"dev": true
},
+ "node-emoji": {
+ "version": "1.10.0",
+ "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-1.10.0.tgz",
+ "integrity": "sha512-Yt3384If5H6BYGVHiHwTL+99OzJKHhgp82S8/dktEK73T26BazdgZ4JZh92xSVtGNJvz9UbXdNAc5hcrXV42vw==",
+ "dev": true,
+ "requires": {
+ "lodash.toarray": "^4.4.0"
+ }
+ },
"node-gyp": {
"version": "3.8.0",
"resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-3.8.0.tgz",
@@ -5058,6 +5250,12 @@
"integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
"dev": true
},
+ "normalize-range": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz",
+ "integrity": "sha1-LRDAa9/TEuqXd2laTShDlFa3WUI=",
+ "dev": true
+ },
"normalize-url": {
"version": "1.9.1",
"resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-1.9.1.tgz",
@@ -5070,6 +5268,12 @@
"sort-keys": "^1.0.0"
}
},
+ "normalize.css": {
+ "version": "8.0.1",
+ "resolved": "https://registry.npmjs.org/normalize.css/-/normalize.css-8.0.1.tgz",
+ "integrity": "sha512-qizSNPO93t1YUuUhP22btGOo3chcvDFqFaj2TRybP0DMxkHOCTYwp3n34fel4a31ORXy4m1Xq0Gyqpb5m33qIg==",
+ "dev": true
+ },
"npmlog": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz",
@@ -5096,6 +5300,12 @@
"boolbase": "~1.0.0"
}
},
+ "num2fraction": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/num2fraction/-/num2fraction-1.2.2.tgz",
+ "integrity": "sha1-b2gragJ6Tp3fpFZM0lidHU5mnt4=",
+ "dev": true
+ },
"number-is-nan": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz",
@@ -5622,6 +5832,108 @@
"postcss": "^7.0.0"
}
},
+ "postcss-functions": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-functions/-/postcss-functions-3.0.0.tgz",
+ "integrity": "sha1-DpTQFERwCkgd4g3k1V+yZAVkJQ4=",
+ "dev": true,
+ "requires": {
+ "glob": "^7.1.2",
+ "object-assign": "^4.1.1",
+ "postcss": "^6.0.9",
+ "postcss-value-parser": "^3.3.0"
+ },
+ "dependencies": {
+ "postcss": {
+ "version": "6.0.23",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz",
+ "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==",
+ "dev": true,
+ "requires": {
+ "chalk": "^2.4.1",
+ "source-map": "^0.6.1",
+ "supports-color": "^5.4.0"
+ }
+ },
+ "postcss-value-parser": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz",
+ "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==",
+ "dev": true
+ },
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ }
+ }
+ },
+ "postcss-import": {
+ "version": "12.0.1",
+ "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-12.0.1.tgz",
+ "integrity": "sha512-3Gti33dmCjyKBgimqGxL3vcV8w9+bsHwO5UrBawp796+jdardbcFl4RP5w/76BwNL7aGzpKstIfF9I+kdE8pTw==",
+ "dev": true,
+ "requires": {
+ "postcss": "^7.0.1",
+ "postcss-value-parser": "^3.2.3",
+ "read-cache": "^1.0.0",
+ "resolve": "^1.1.7"
+ },
+ "dependencies": {
+ "postcss-value-parser": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz",
+ "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==",
+ "dev": true
+ }
+ }
+ },
+ "postcss-js": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-2.0.3.tgz",
+ "integrity": "sha512-zS59pAk3deu6dVHyrGqmC3oDXBdNdajk4k1RyxeVXCrcEDBUBHoIhE4QTsmhxgzXxsaqFDAkUZfmMa5f/N/79w==",
+ "dev": true,
+ "requires": {
+ "camelcase-css": "^2.0.1",
+ "postcss": "^7.0.18"
+ }
+ },
+ "postcss-load-config": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-2.1.0.tgz",
+ "integrity": "sha512-4pV3JJVPLd5+RueiVVB+gFOAa7GWc25XQcMp86Zexzke69mKf6Nx9LRcQywdz7yZI9n1udOxmLuAwTBypypF8Q==",
+ "dev": true,
+ "requires": {
+ "cosmiconfig": "^5.0.0",
+ "import-cwd": "^2.0.0"
+ }
+ },
+ "postcss-loader": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-3.0.0.tgz",
+ "integrity": "sha512-cLWoDEY5OwHcAjDnkyRQzAXfs2jrKjXpO/HQFcc5b5u/r7aa471wdmChmwfnv7x2u840iat/wi0lQ5nbRgSkUA==",
+ "dev": true,
+ "requires": {
+ "loader-utils": "^1.1.0",
+ "postcss": "^7.0.0",
+ "postcss-load-config": "^2.0.0",
+ "schema-utils": "^1.0.0"
+ },
+ "dependencies": {
+ "schema-utils": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz",
+ "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==",
+ "dev": true,
+ "requires": {
+ "ajv": "^6.1.0",
+ "ajv-errors": "^1.0.0",
+ "ajv-keywords": "^3.1.0"
+ }
+ }
+ }
+ },
"postcss-merge-longhand": {
"version": "4.0.11",
"resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-4.0.11.tgz",
@@ -5795,6 +6107,16 @@
"postcss": "^7.0.6"
}
},
+ "postcss-nested": {
+ "version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-4.2.3.tgz",
+ "integrity": "sha512-rOv0W1HquRCamWy2kFl3QazJMMe1ku6rCFoAAH+9AcxdbpDeBr6k968MLWuLjvjMcGEip01ak09hKOEgpK9hvw==",
+ "dev": true,
+ "requires": {
+ "postcss": "^7.0.32",
+ "postcss-selector-parser": "^6.0.2"
+ }
+ },
"postcss-normalize-charset": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-4.0.1.tgz",
@@ -6069,6 +6391,12 @@
"integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=",
"dev": true
},
+ "pretty-hrtime": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz",
+ "integrity": "sha1-t+PqQkNaTJsnWdmeDyAesZWALuE=",
+ "dev": true
+ },
"process": {
"version": "0.11.10",
"resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz",
@@ -6166,6 +6494,26 @@
"integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
"dev": true
},
+ "purgecss": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/purgecss/-/purgecss-2.3.0.tgz",
+ "integrity": "sha512-BE5CROfVGsx2XIhxGuZAT7rTH9lLeQx/6M0P7DTXQH4IUc3BBzs9JUzt4yzGf3JrH9enkeq6YJBe9CTtkm1WmQ==",
+ "dev": true,
+ "requires": {
+ "commander": "^5.0.0",
+ "glob": "^7.0.0",
+ "postcss": "7.0.32",
+ "postcss-selector-parser": "^6.0.2"
+ },
+ "dependencies": {
+ "commander": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz",
+ "integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==",
+ "dev": true
+ }
+ }
+ },
"q": {
"version": "1.5.1",
"resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz",
@@ -6219,6 +6567,23 @@
"safe-buffer": "^5.1.0"
}
},
+ "read-cache": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz",
+ "integrity": "sha1-5mTvMRYRZsl1HNvo28+GtftY93Q=",
+ "dev": true,
+ "requires": {
+ "pify": "^2.3.0"
+ },
+ "dependencies": {
+ "pify": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
+ "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
+ "dev": true
+ }
+ }
+ },
"read-pkg": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz",
@@ -6315,6 +6680,24 @@
"strip-indent": "^1.0.1"
}
},
+ "reduce-css-calc": {
+ "version": "2.1.7",
+ "resolved": "https://registry.npmjs.org/reduce-css-calc/-/reduce-css-calc-2.1.7.tgz",
+ "integrity": "sha512-fDnlZ+AybAS3C7Q9xDq5y8A2z+lT63zLbynew/lur/IR24OQF5x98tfNwf79mzEdfywZ0a2wpM860FhFfMxZlA==",
+ "dev": true,
+ "requires": {
+ "css-unit-converter": "^1.1.1",
+ "postcss-value-parser": "^3.3.0"
+ },
+ "dependencies": {
+ "postcss-value-parser": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz",
+ "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==",
+ "dev": true
+ }
+ }
+ },
"regenerate": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.1.tgz",
@@ -7255,6 +7638,85 @@
"util.promisify": "~1.0.0"
}
},
+ "tailwindcss": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-1.6.0.tgz",
+ "integrity": "sha512-UZEex5ebsQlCTIBjI0oZITL67HBjOrzMgA4ceLOf8mrBGquLSn7LsO92do1nBSBZBV2Qqpivz9QUwT3zMSQkMA==",
+ "dev": true,
+ "requires": {
+ "@fullhuman/postcss-purgecss": "^2.1.2",
+ "autoprefixer": "^9.4.5",
+ "browserslist": "^4.12.0",
+ "bytes": "^3.0.0",
+ "chalk": "^3.0.0 || ^4.0.0",
+ "color": "^3.1.2",
+ "detective": "^5.2.0",
+ "fs-extra": "^8.0.0",
+ "lodash": "^4.17.15",
+ "node-emoji": "^1.8.1",
+ "normalize.css": "^8.0.1",
+ "postcss": "^7.0.11",
+ "postcss-functions": "^3.0.0",
+ "postcss-js": "^2.0.0",
+ "postcss-nested": "^4.1.1",
+ "postcss-selector-parser": "^6.0.0",
+ "pretty-hrtime": "^1.0.3",
+ "reduce-css-calc": "^2.1.6",
+ "resolve": "^1.14.2"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz",
+ "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==",
+ "dev": true,
+ "requires": {
+ "@types/color-name": "^1.1.1",
+ "color-convert": "^2.0.1"
+ }
+ },
+ "chalk": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz",
+ "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
+ },
+ "color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "requires": {
+ "color-name": "~1.1.4"
+ }
+ },
+ "color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ },
+ "has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz",
+ "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
+ }
+ }
+ },
"tapable": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz",
@@ -7618,6 +8080,12 @@
"imurmurhash": "^0.1.4"
}
},
+ "universalify": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz",
+ "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==",
+ "dev": true
+ },
"unquote": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/unquote/-/unquote-1.1.1.tgz",
diff --git a/assets/package.json b/assets/package.json
index 15b2010..c97d597 100644
--- a/assets/package.json
+++ b/assets/package.json
@@ -3,15 +3,16 @@
"description": " ",
"license": "MIT",
"scripts": {
- "deploy": "webpack --mode production",
+ "deploy": "NODE_ENV=production webpack --mode production",
"watch": "webpack --mode development --watch"
},
"dependencies": {
+ "@fortawesome/fontawesome-free": "^5.14.0",
"lodash": ">=4.17.19",
+ "nprogress": "^0.2.0",
"phoenix": "file:../deps/phoenix",
"phoenix_html": "file:../deps/phoenix_html",
- "phoenix_live_view": "file:../deps/phoenix_live_view",
- "nprogress": "^0.2.0"
+ "phoenix_live_view": "file:../deps/phoenix_live_view"
},
"devDependencies": {
"@babel/core": "^7.10.5",
@@ -19,10 +20,15 @@
"babel-loader": "^8.1.0",
"copy-webpack-plugin": "^6.0.3",
"css-loader": "^3.6.0",
+ "file-loader": "^6.0.0",
+ "lato-font": "^3.0.0",
"mini-css-extract-plugin": "^0.9.0",
"node-sass": "^4.14.1",
"optimize-css-assets-webpack-plugin": "^5.0.3",
+ "postcss-import": "^12.0.1",
+ "postcss-loader": "^3.0.0",
"sass-loader": "^9.0.2",
+ "tailwindcss": "^1.6.0",
"terser-webpack-plugin": "^3.0.7",
"webpack": "4.43.0",
"webpack-cli": "^3.3.12"
diff --git a/assets/postcss.config.js b/assets/postcss.config.js
new file mode 100644
index 0000000..7ddb3f7
--- /dev/null
+++ b/assets/postcss.config.js
@@ -0,0 +1,7 @@
+module.exports = {
+ plugins: [
+ require("postcss-import"),
+ require("tailwindcss"),
+ require("autoprefixer")
+ ]
+}
diff --git a/assets/tailwind.config.js b/assets/tailwind.config.js
new file mode 100644
index 0000000..4a2996a
--- /dev/null
+++ b/assets/tailwind.config.js
@@ -0,0 +1,28 @@
+module.exports = {
+ purge: [
+ "../**/*.html.eex",
+ "../**/*.html.leex",
+ "../**/views/**/*.ex",
+ "../**/live/**/*.ex",
+ "./js/**/*.js"
+ ],
+ theme: {
+ extend: {
+ colors: {
+ blue: {
+ 100: "#cedbf2",
+ 600: "#718096",
+ 700: "#4a5568",
+ 800: "#2d3748"
+ },
+ gray: {
+ 700: "#595959",
+ 800: "#333333",
+ 900: "#202020"
+ }
+ }
+ },
+ },
+ variants: {},
+ plugins: [],
+}
diff --git a/assets/webpack.config.js b/assets/webpack.config.js
index 917121e..c9cd0bd 100644
--- a/assets/webpack.config.js
+++ b/assets/webpack.config.js
@@ -16,7 +16,16 @@ module.exports = (env, options) => {
]
},
entry: {
- 'app': glob.sync('./vendor/**/*.js').concat(['./js/app.js'])
+ 'app': glob.sync('./vendor/**/*.js')
+ .concat([
+ './node_modules/@fortawesome/fontawesome-free/webfonts/fa-solid-900.woff',
+ './node_modules/@fortawesome/fontawesome-free/webfonts/fa-solid-900.woff2',
+ './node_modules/lato-font/fonts/lato-light/lato-light.woff',
+ './node_modules/lato-font/fonts/lato-light/lato-light.woff2',
+ './node_modules/lato-font/fonts/lato-normal/lato-normal.woff',
+ './node_modules/lato-font/fonts/lato-normal/lato-normal.woff2',
+ ])
+ .concat(['./js/app.js'])
},
output: {
filename: '[name].js',
@@ -39,6 +48,16 @@ module.exports = (env, options) => {
MiniCssExtractPlugin.loader,
'css-loader',
'sass-loader',
+ 'postcss-loader',
+ ],
+ },
+ {
+ test: /\.(woff(2)?|ttf|eot|svg)(\?v=\d+\.\d+\.\d+)?$/,
+ use: [
+ {
+ loader: 'file-loader',
+ options: { name: '[name].[ext]', outputPath: '../fonts' }
+ },
],
}
]
diff --git a/lib/xebow_web/live/animation_config_integer_component.html.leex b/lib/xebow_web/live/animation_config_integer_component.html.leex
index 101d7a6..c03ed5a 100644
--- a/lib/xebow_web/live/animation_config_integer_component.html.leex
+++ b/lib/xebow_web/live/animation_config_integer_component.html.leex
@@ -1,21 +1,20 @@
-
-
-
-
-
- <%= @value %>
-
-
-
+
diff --git a/lib/xebow_web/live/animation_config_option_component.html.leex b/lib/xebow_web/live/animation_config_option_component.html.leex
index 2340d6e..87d7f24 100644
--- a/lib/xebow_web/live/animation_config_option_component.html.leex
+++ b/lib/xebow_web/live/animation_config_option_component.html.leex
@@ -1,14 +1,16 @@
-
-
-
-
-
+
diff --git a/lib/xebow_web/live/matrix_live.ex b/lib/xebow_web/live/matrix_live.ex
index 0e31ca1..17d9fe0 100644
--- a/lib/xebow_web/live/matrix_live.ex
+++ b/lib/xebow_web/live/matrix_live.ex
@@ -141,8 +141,8 @@ defmodule XebowWeb.MatrixLive do
defp make_view_led(color_hex, led, nil) do
width = 25
height = 25
- x = led.x * 50 - width / 2
- y = led.y * 50 - height / 2
+ x = led.x * 72 - width / 2
+ y = led.y * 72 - height / 2
%{
class: "led",
@@ -156,10 +156,10 @@ defmodule XebowWeb.MatrixLive do
end
defp make_view_led(color_hex, _led, key) do
- width = key.width * 50
- height = key.height * 50
- x = key.x * 50 - width / 2
- y = key.y * 50 - height / 2
+ width = key.width * 70
+ height = key.height * 70
+ x = key.x * 72 - width / 2
+ y = key.y * 72 - height / 2
%{
class: "key",
diff --git a/lib/xebow_web/live/matrix_live.html.leex b/lib/xebow_web/live/matrix_live.html.leex
index 52fd16b..2ac3c19 100644
--- a/lib/xebow_web/live/matrix_live.html.leex
+++ b/lib/xebow_web/live/matrix_live.html.leex
@@ -1,36 +1,36 @@
-
-
-
+
+
+
Animation
+
+
+ <%= live_component @socket, XebowWeb.AnimationConfigComponent, schema: @config_schema, config: @config %>
-
-
-
-
-
-
-
-
- <%= for led <- @leds do %>
-
- phx-click="key_pressed"
- phx-value-key-id="<%= led.id %>"
+
+
+
+ <%= for led <- @leds do %>
+
+ phx-click="key_pressed"
+ phx-value-key-id="<%= led.id %>"
+ <% end %>
+ phx-hook="AnimationColorUpdate"
+ style="
+ left: <%= led.x %>px;
+ top: <%= led.y %>px;
+ width: <%= led.width %>px;
+ height: <%= led.height %>px;
+ background-color: #<%= led.color %>
+ "
+ >
<% end %>
- phx-hook="AnimationColorUpdate"
- style="
- left: <%= led.x %>px;
- top: <%= led.y %>px;
- width: <%= led.width %>px;
- height: <%= led.height %>px;
- background-color: #<%= led.color %>
- "
- >
- <% end %>
+
+
-
-
-
-<%= live_component @socket, XebowWeb.AnimationConfigComponent, schema: @config_schema, config: @config %>
diff --git a/lib/xebow_web/templates/layout/_nav.html.eex b/lib/xebow_web/templates/layout/_nav.html.eex
new file mode 100644
index 0000000..a534df6
--- /dev/null
+++ b/lib/xebow_web/templates/layout/_nav.html.eex
@@ -0,0 +1,8 @@
+
diff --git a/lib/xebow_web/templates/layout/app.html.eex b/lib/xebow_web/templates/layout/app.html.eex
index 09ffdad..0278382 100644
--- a/lib/xebow_web/templates/layout/app.html.eex
+++ b/lib/xebow_web/templates/layout/app.html.eex
@@ -1,4 +1,4 @@
-
+
<%= get_flash(@conn, :info) %>
<%= get_flash(@conn, :error) %>
<%= @inner_content %>
diff --git a/lib/xebow_web/templates/layout/live.html.leex b/lib/xebow_web/templates/layout/live.html.leex
index 8dcded5..8225c1d 100644
--- a/lib/xebow_web/templates/layout/live.html.leex
+++ b/lib/xebow_web/templates/layout/live.html.leex
@@ -1,4 +1,4 @@
-
+
<%= live_flash(@flash, :info) %>
diff --git a/lib/xebow_web/templates/layout/root.html.leex b/lib/xebow_web/templates/layout/root.html.leex
index 7cfb577..fdcd9bc 100644
--- a/lib/xebow_web/templates/layout/root.html.leex
+++ b/lib/xebow_web/templates/layout/root.html.leex
@@ -10,23 +10,7 @@
-
+ <%= render "_nav.html" %>
<%= @inner_content %>