]> git.cworth.org Git - lmno.games/commitdiff
Merge in empires-html client
authorCarl Worth <cworth@cworth.org>
Sun, 17 May 2020 14:53:51 +0000 (07:53 -0700)
committerCarl Worth <cworth@cworth.org>
Sun, 17 May 2020 14:53:51 +0000 (07:53 -0700)
This HTML client for the empires game was originally developed in a
separate repository (and at the top-level).

In order to create this commit, I first rewrote the history of the
empires-html repository with:

git-filter-repo --path-rename '':empires/

to move all of its content down into the empires sub-directory.

I then fetched things over to thi repository with:

git fetch ../empires-html-filtered
        git merge --allow-unrelated-histories FETCH_HEAD

Going forward, we can develop the empires client within a
sub-directory of the lmno.games content (so they can share common
resources such as reset.css and style.css, etc.).

17 files changed:
Makefile [new file with mode: 0644]
android-chrome-192x192.png [new file with mode: 0644]
android-chrome-512x512.png [new file with mode: 0644]
apple-touch-icon.png [new file with mode: 0644]
browserconfig.xml [new file with mode: 0644]
favicon-16x16.png [new file with mode: 0644]
favicon-32x32.png [new file with mode: 0644]
favicon.ico [new file with mode: 0644]
index.html [new file with mode: 0644]
lmno.js [new file with mode: 0644]
lmno.png [new file with mode: 0644]
lmno.svg [new file with mode: 0644]
mstile-150x150.png [new file with mode: 0644]
reset.css [new file with mode: 0644]
safari-pinned-tab.svg [new file with mode: 0644]
site.webmanifest [new file with mode: 0644]
style.css [new file with mode: 0644]

diff --git a/Makefile b/Makefile
new file mode 100644 (file)
index 0000000..fb39f7f
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,12 @@
+DEPLOY_HOST=lmno.games
+DEPLOY_DIR=/srv/lmno.games/www
+DO_NOT_DEPLOY="Makefile"
+
+deploy:
+       rm -rf .deploy-source
+       git clone . .deploy-source
+       rm -rf .deploy-source/.git
+       (cd .deploy-source; rsync -avz \
+               --exclude=$(DO_NOT_DEPLOY) \
+               ./ $(DEPLOY_HOST):$(DEPLOY_DIR) )
+       rm -rf .deploy-source
diff --git a/android-chrome-192x192.png b/android-chrome-192x192.png
new file mode 100644 (file)
index 0000000..e9ae90a
Binary files /dev/null and b/android-chrome-192x192.png differ
diff --git a/android-chrome-512x512.png b/android-chrome-512x512.png
new file mode 100644 (file)
index 0000000..04d98ec
Binary files /dev/null and b/android-chrome-512x512.png differ
diff --git a/apple-touch-icon.png b/apple-touch-icon.png
new file mode 100644 (file)
index 0000000..ce22c46
Binary files /dev/null and b/apple-touch-icon.png differ
diff --git a/browserconfig.xml b/browserconfig.xml
new file mode 100644 (file)
index 0000000..249c5c1
--- /dev/null
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+<browserconfig>
+    <msapplication>
+        <tile>
+            <square150x150logo src="/mstile-150x150.png"/>
+            <TileColor>#ffc40d</TileColor>
+        </tile>
+    </msapplication>
+</browserconfig>
diff --git a/favicon-16x16.png b/favicon-16x16.png
new file mode 100644 (file)
index 0000000..30073b8
Binary files /dev/null and b/favicon-16x16.png differ
diff --git a/favicon-32x32.png b/favicon-32x32.png
new file mode 100644 (file)
index 0000000..ba9d653
Binary files /dev/null and b/favicon-32x32.png differ
diff --git a/favicon.ico b/favicon.ico
new file mode 100644 (file)
index 0000000..b2c0d81
Binary files /dev/null and b/favicon.ico differ
diff --git a/index.html b/index.html
new file mode 100644 (file)
index 0000000..c4ed9d7
--- /dev/null
@@ -0,0 +1,50 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta charset="utf-8"/>
+
+    <title>LMNO Games</title>
+
+    <link rel="stylesheet" href="/reset.css" type="text/css" />
+    <link rel="stylesheet" href="/style.css" type="text/css" />
+
+    <link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png">
+    <link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png">
+    <link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png">
+    <link rel="manifest" href="/site.webmanifest">
+    <link rel="mask-icon" href="/safari-pinned-tab.svg" color="#5bbad5">
+    <meta name="msapplication-TileColor" content="#ffc40d">
+    <meta name="theme-color" content="#ffffff">
+
+  </head>
+  <body>
+
+    <script src="/lmno.js"></script>
+
+    <div id="page">
+
+      <div id="message-area">
+      </div>
+
+      <form onsubmit="lmno_join(this); return false">
+
+        <div class="form-field large">
+          <label for="id">Game ID</label>
+          <input type="text" id="id" maxlength="4"
+                 placeholder="Enter a 4-letter Game Code"
+                 oninput="this.value = this.value.toUpperCase()"
+                 autocomplete="off"
+                 required>
+        </div>
+
+        <div class="form-field large">
+          <button type="submit">
+            Join Game
+          </button>
+        </div>
+
+      </form>
+
+    </div>
+  </body>
+</html>
diff --git a/lmno.js b/lmno.js
new file mode 100644 (file)
index 0000000..f1f9cd7
--- /dev/null
+++ b/lmno.js
@@ -0,0 +1,32 @@
+function undisplay(element) {
+  element.style.display="none";
+}
+
+function add_message(severity, message) {
+  message = `<div class="message ${severity}" onclick="undisplay(this)">
+<span class="hide-button" onclick="undisplay(this.parentElement)">&times;</span>
+${message}
+</div>`;
+  const message_area = document.getElementById('message-area');
+  message_area.insertAdjacentHTML('beforeend', message);
+}
+
+function join_loadend(request, game_id) {
+  if (request.status === 404) {
+    add_message("danger", game_id + " is not a valid game ID. Try again.");
+    return;
+  }
+}
+
+function lmno_join(form) {
+  const game_id = form.id.value;
+
+  var request = new XMLHttpRequest();
+  request.addEventListener("loadend", () => join_loadend(request, game_id));
+
+  request.open("GET", "/" + game_id);
+  request.setRequestHeader("Content-Type", "application/json; charset=UTF-8");
+  request.send();
+
+  form.reset();
+}
diff --git a/lmno.png b/lmno.png
new file mode 100644 (file)
index 0000000..ade22e8
Binary files /dev/null and b/lmno.png differ
diff --git a/lmno.svg b/lmno.svg
new file mode 100644 (file)
index 0000000..d865617
--- /dev/null
+++ b/lmno.svg
@@ -0,0 +1,80 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="260"
+   height="260"
+   viewBox="0 0 41.275 41.275"
+   version="1.1"
+   id="svg8"
+   inkscape:version="0.92.5 (2060ec1f9f, 2020-04-08)"
+   sodipodi:docname="lmno.svg">
+  <defs
+     id="defs2" />
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="1.979899"
+     inkscape:cx="99.276015"
+     inkscape:cy="131.79368"
+     inkscape:document-units="mm"
+     inkscape:current-layer="layer1"
+     showgrid="false"
+     units="px"
+     scale-x="0.6"
+     inkscape:window-width="1899"
+     inkscape:window-height="1436"
+     inkscape:window-x="0"
+     inkscape:window-y="0"
+     inkscape:window-maximized="0" />
+  <metadata
+     id="metadata5">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title></dc:title>
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer"
+     id="layer1"
+     transform="translate(0,-228.20834)">
+    <path
+       sodipodi:nodetypes="ccccccc"
+       inkscape:connector-curvature="0"
+       id="path4524"
+       style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:23.28333282px;line-height:16.39887428px;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Bold';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.04445;stroke-linecap:butt;stroke-miterlimit:10;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+       d="m 2.6520348,230.16805 h 4.3769937 v 13.66532 H 18.081943 v 3.30832 H 2.6520348 Z" />
+    <path
+       inkscape:connector-curvature="0"
+       id="path4526"
+       style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:23.28333282px;line-height:16.39887428px;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Bold';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.04445;stroke-linecap:butt;stroke-miterlimit:10;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+       d="m 19.739363,230.16805 h 5.570719 l 3.865397,9.08369 3.888135,-9.08369 h 5.559351 v 16.97364 h -4.138249 v -12.41474 l -3.910872,9.15189 h -2.773991 l -3.910873,-9.15189 v 12.41474 h -4.149617 z" />
+    <path
+       inkscape:connector-curvature="0"
+       id="path4528"
+       style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:23.28333282px;line-height:16.39887428px;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Bold';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.04445;stroke-linecap:butt;stroke-miterlimit:10;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+       d="m 2.6520348,250.22028 h 4.8885904 l 6.1732668,11.64167 v -11.64167 h 4.149617 v 16.97364 h -4.88859 L 6.8016522,255.55225 v 11.64167 H 2.6520348 Z" />
+    <path
+       inkscape:connector-curvature="0"
+       id="path4530"
+       style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:23.28333282px;line-height:16.39887428px;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Bold';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.04445;stroke-linecap:butt;stroke-miterlimit:10;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+       d="m 29.891715,252.75553 q -2.000911,0 -3.103686,1.47795 -1.102775,1.47794 -1.102775,4.16098 0,2.67167 1.102775,4.14962 1.102775,1.47795 3.103686,1.47795 2.012281,0 3.115056,-1.47795 1.102775,-1.47795 1.102775,-4.14962 0,-2.68304 -1.102775,-4.16098 -1.102775,-1.47795 -3.115056,-1.47795 z m 0,-3.1719 q 4.092774,0 6.412012,2.34198 2.319238,2.34197 2.319238,6.46885 0,4.11551 -2.319238,6.45749 -2.319238,2.34197 -6.412012,2.34197 -4.081404,0 -6.412011,-2.34197 -2.319238,-2.34198 -2.319238,-6.45749 0,-4.12688 2.319238,-6.46885 2.330607,-2.34198 6.412011,-2.34198 z" />
+  </g>
+</svg>
diff --git a/mstile-150x150.png b/mstile-150x150.png
new file mode 100644 (file)
index 0000000..4127bdd
Binary files /dev/null and b/mstile-150x150.png differ
diff --git a/reset.css b/reset.css
new file mode 100644 (file)
index 0000000..e29c0f5
--- /dev/null
+++ b/reset.css
@@ -0,0 +1,48 @@
+/* http://meyerweb.com/eric/tools/css/reset/ 
+   v2.0 | 20110126
+   License: none (public domain)
+*/
+
+html, body, div, span, applet, object, iframe,
+h1, h2, h3, h4, h5, h6, p, blockquote, pre,
+a, abbr, acronym, address, big, cite, code,
+del, dfn, em, img, ins, kbd, q, s, samp,
+small, strike, strong, sub, sup, tt, var,
+b, u, i, center,
+dl, dt, dd, ol, ul, li,
+fieldset, form, label, legend,
+table, caption, tbody, tfoot, thead, tr, th, td,
+article, aside, canvas, details, embed, 
+figure, figcaption, footer, header, hgroup, 
+menu, nav, output, ruby, section, summary,
+time, mark, audio, video {
+       margin: 0;
+       padding: 0;
+       border: 0;
+       font-size: 100%;
+       font: inherit;
+       vertical-align: baseline;
+}
+/* HTML5 display-role reset for older browsers */
+article, aside, details, figcaption, figure, 
+footer, header, hgroup, menu, nav, section {
+       display: block;
+}
+body {
+       line-height: 1;
+}
+ol, ul {
+       list-style: none;
+}
+blockquote, q {
+       quotes: none;
+}
+blockquote:before, blockquote:after,
+q:before, q:after {
+       content: '';
+       content: none;
+}
+table {
+       border-collapse: collapse;
+       border-spacing: 0;
+}
diff --git a/safari-pinned-tab.svg b/safari-pinned-tab.svg
new file mode 100644 (file)
index 0000000..4b1730f
--- /dev/null
@@ -0,0 +1,42 @@
+<?xml version="1.0" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
+ "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
+<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
+ width="585.000000pt" height="585.000000pt" viewBox="0 0 585.000000 585.000000"
+ preserveAspectRatio="xMidYMid meet">
+<metadata>
+Created by potrace 1.11, written by Peter Selinger 2001-2013
+</metadata>
+<g transform="translate(0.000000,585.000000) scale(0.100000,-0.100000)"
+fill="#000000" stroke="none">
+<path d="M410 5570 l-35 -5 0 -1190 c0 -655 3 -1194 7 -1200 7 -11 2155 -14
+2173 -3 8 5 13 421 6 458 -1 3 -346 5 -768 5 -423 0 -775 1 -783 3 -13 3 -15
+118 -14 968 l0 964 -35 1 c-154 4 -523 3 -551 -1z"/>
+<path d="M2820 5572 l-25 -3 1 -1193 c0 -656 3 -1197 6 -1202 5 -7 441 -11
+563 -5 20 1 21 4 20 871 0 479 1 870 3 870 3 0 43 -87 72 -155 6 -16 117 -275
+245 -575 l233 -545 94 -5 c51 -3 140 -4 198 -2 l105 3 209 492 c116 271 222
+519 236 552 15 33 42 96 60 140 18 44 37 84 41 89 5 5 8 -332 8 -750 0 -417 0
+-811 1 -874 l0 -115 286 0 c197 1 287 4 292 12 9 14 9 2380 0 2388 -5 5 -626
+9 -758 6 -23 -1 -30 -12 -64 -93 -22 -51 -50 -117 -62 -146 -13 -29 -36 -80
+-50 -115 -14 -34 -34 -80 -44 -102 -10 -22 -93 -217 -185 -434 l-168 -394 -22
+49 c-12 27 -29 65 -37 84 -17 38 -14 30 -283 665 -102 242 -191 450 -197 463
+-10 19 -19 22 -77 23 -398 3 -681 3 -701 1z"/>
+<path d="M4068 2815 c-1 -1 -26 -5 -55 -9 -492 -58 -851 -368 -967 -837 -35
+-143 -41 -197 -40 -399 0 -198 6 -255 39 -391 148 -598 653 -910 1371 -846
+174 16 382 79 513 157 288 169 485 479 526 825 3 28 8 62 11 77 10 50 6 323
+-6 408 -32 236 -105 423 -229 586 -71 94 -183 198 -271 251 -141 86 -257 126
+-480 169 -35 6 -405 15 -412 9z m315 -461 c151 -34 283 -144 354 -294 42 -88
+78 -215 89 -310 7 -65 7 -347 0 -358 -3 -5 -7 -29 -10 -54 -3 -26 -11 -59 -17
+-75 -6 -15 -10 -29 -9 -31 6 -11 -19 -79 -56 -153 -108 -212 -279 -310 -529
+-303 -259 8 -452 178 -526 464 -55 214 -46 541 21 736 68 195 214 337 393 379
+70 17 214 16 290 -1z"/>
+<path d="M378 2723 c-4 -7 -2 -2360 1 -2388 1 -12 559 -15 576 -3 7 4 10 287
+10 817 0 446 2 811 5 811 3 0 10 -10 15 -23 10 -20 51 -99 175 -332 21 -38 63
+-119 95 -180 31 -60 70 -132 85 -160 15 -27 51 -95 80 -150 29 -55 70 -131 90
+-170 36 -68 90 -170 172 -325 105 -199 152 -285 155 -290 3 -3 160 -5 349 -5
+l344 -1 0 1203 0 1203 -292 -2 -293 -3 0 -813 c0 -446 -3 -812 -6 -812 -3 0
+-21 28 -39 63 -64 121 -123 233 -160 302 -21 39 -61 115 -90 170 -29 55 -67
+127 -85 160 -18 33 -54 101 -80 150 -26 50 -64 122 -85 160 -72 134 -118 221
+-186 350 -37 72 -85 162 -105 200 l-38 70 -345 3 c-189 1 -346 -1 -348 -5z"/>
+</g>
+</svg>
diff --git a/site.webmanifest b/site.webmanifest
new file mode 100644 (file)
index 0000000..a7423e1
--- /dev/null
@@ -0,0 +1,19 @@
+{
+    "name": "LMNO Games",
+    "short_name": "LMNO",
+    "icons": [
+        {
+            "src": "/android-chrome-192x192.png",
+            "sizes": "192x192",
+            "type": "image/png"
+        },
+        {
+            "src": "/android-chrome-512x512.png",
+            "sizes": "512x512",
+            "type": "image/png"
+        }
+    ],
+    "theme_color": "#ffffff",
+    "background_color": "#ffffff",
+    "display": "standalone"
+}
diff --git a/style.css b/style.css
new file mode 100644 (file)
index 0000000..fdc99c9
--- /dev/null
+++ b/style.css
@@ -0,0 +1,257 @@
+/*\
+|*|
+|*| Core elements: Sizing and padding
+|*|
+\*/
+
+body {
+    line-height: 1.5;
+    font-family: sans-serif;
+}
+
+h1 {
+    font-size: 150%;
+    font-weight: bold;
+}
+
+h2 {
+    font-size: 110%;
+    font-weight: bold;
+}
+
+/*\
+|*|
+|*| Overall page layout
+|*|
+|*| Assumes: Top-level div with id="page" for all content
+|*|
+\*/
+
+/* Mobile-first: At small sized we have a white background and use the
+ * entire screen width for the page (so the background color of the
+ * body is not visible anywhere). */
+body {
+    background-color: #333738;
+}
+
+#page {
+    background-color: white;
+}
+
+/* For a small screen (in either width or height) change the
+ * background of the body element to white so the application always
+ * appears as if it is "full screen".
+ */
+@media screen and (max-width: 500px) and (max-height: 860px) {
+    body {
+        background-color: white;
+    }
+}
+
+/* We never let the page content get larger than a large fixed width.
+ *
+ * And when the screen is wide enough, we can afford some "wasted"
+ * space on either side of the page content. This starts at 0 for a
+ * 620px wide page up to 50px on either side for a 720px wide page.
+ *
+ * Wider than that and we start to see the background on either side
+ * of the page content.
+ */
+#page {
+    box-sizing: border-box;
+    max-width: 720px;
+    margin-left: auto;
+    margin-right: auto;
+    padding-top: 0;
+    padding-bottom: 0;
+    padding-left: 1em;
+    padding-right: 1em;
+}
+
+@media screen and (min-width: 620px) and (max-width: 720px) {
+    #page {
+        padding-left: calc(1em + (100% - 620px)/2);
+        padding-right: calc(1em + (100% - 620px)/2);
+    }
+}
+
+@media screen and (min-width: 720px) {
+    #page {
+        padding-left: calc(1em + 50px);
+        padding-right: calc(1em + 50px);
+    }
+}
+
+/* The calculations for height are different. We don't have any
+ * vertical centering, so instead we have only some fixed padding on
+ * the top. Then, the margin which allows the background to be visible
+ * on the top and bottom starts appearing at a viewport height of 648
+ * and tops out at a size of 36px.
+ */
+#page {
+    min-height: 500px;
+    padding-top: 1em;
+}
+
+@media screen and (min-height: 648px) and (max-height: 720px) {
+    #page {
+        margin-top: calc((100vh - 648px)/2);
+        margin-bottom: calc((100vh - 648px)/2);
+    }
+}
+
+@media screen and (min-height: 720px) {
+    #page {
+        margin-top: 36px;
+        margin-bottom: 36px;
+    }
+}
+
+/*\
+|*|
+|*| Responsive form layout
+|*|
+\*/
+
+/*
+ *
+ * Within the form, fields can be placed in <div> elements with
+ * class "form-field". Each can also have an additional class of one
+ * of "small", "medium", or "large". These classes will be used to
+ * select either a 1- or 2-column layout for each row depending on the
+ * width of the screen.
+ *
+ * Expected layout is as follows:
+ *
+ *   "large"   rows: 1-column on all devices
+ *
+ *   "medium"  rows: 2-column on wide displays (laptop/desktop/tablet)
+ *                   1-column on small display (phones)
+ *
+ *   "small"   rows: 2-column on all devices
+ *
+ * Finally, a class of either "left" or "right" will select which
+ * column the field should appear in for fields that end up in 2
+ * columns.
+ */
+form {
+    max-width: 100%;
+    display: grid;
+    grid-template-columns: 1fr 1fr;
+    grid-column-gap: 1em;
+}
+
+.form-field.small.left,.form-field.medium.left {
+    grid-column-start: 1;
+}
+
+.form-field.small.right,.form-field.medium.right {
+    grid-column-start: 2;
+}
+
+.form-field.large {
+    grid-column-start: 1;
+    grid-column-end: span 2;
+}
+
+/* For a narrow screen, use a single-column for medium form fields. */
+@media screen and (max-width: 600px) {
+    .form-field.medium.left,.form-field.medium.right {
+       grid-column-start: 1;
+        grid-column-end: span 2
+    }
+}
+
+/*\
+|*|
+|*| Styling for form input fields
+|*|
+\*/
+
+label {
+    font-size: 125%;
+}
+
+input {
+    box-sizing: border-box;
+    font-size: 125%;
+    padding: 0.5em;
+    width: 100%;
+    border: 1px solid #287789;
+    border-radius: 4px;
+}
+
+input:focus {
+    border: 2px solid #44c7ef;
+}
+
+button {
+    display: inline-block;
+    border-radius: 4px;
+    background-color: #287789;
+    border: none;
+    color: white;
+    text-align: center;
+    font-size: 125%;
+    margin-top: .25em;
+    padding-top: 0.25em;
+    padding-bottom: 0.25em;
+    width: 200px;
+}
+
+button:hover {
+    transform: translateY(-1px);
+    background-color: #44c7ef;
+}
+
+:focus {
+    outline: none;
+}
+
+::-moz-focus-inner {
+    border: 0;
+}
+
+/*\
+|*|
+|*| Styling for a message area
+|*|
+\*/
+
+/* Default message severity is "info" but can be overriden. */
+.message {
+    padding: 1em;
+    background-color: #44c7ef;
+    color: white;
+    transition: 0.3s;
+    margin-bottom: 0.5em;
+    font-weight: bold;
+    border-radius: 4px;
+    position: relative;
+}
+
+.success {
+    background-color: #44c7ef;
+}
+
+.warning {
+    background-color: #ffa92a;
+}
+
+.danger {
+    background-color: #f56257
+}
+
+.hide-button {
+    color: white;
+    font-size: 125%;
+    font-weight: bold;
+    cursor: pointer;
+    position: absolute;
+    right: 0.5em;
+    top: 0;
+}
+
+.hide-button:hover {
+    color: #bc2822;
+}