Browse Source

Add references

Craig Fletcher 5 years ago
parent
commit
a36ef3bfbd

+ 12 - 12
.npm-scripts/build-pipeline.js

@@ -53,13 +53,13 @@ module.exports = {
     [
       {
         func: "readInFile",
-        selector: ({ selectMany }) => selectMany(item => Boolean(item.path))
+        selector: state => state.selectAll()
       }
     ],
     [
       {
         func: "decorateFileObject",
-        selector: ({ selectMany }) => selectMany(item => true),
+        selector: state => state.selectAll(),
         config: {
           decorators: [meta]
         }
@@ -68,29 +68,29 @@ module.exports = {
     [
       {
         func: "markdownToHtml",
-        selector: ({ selectByTag }) => selectByTag("markdown")
+        selector: state => state.selectByTag("markdown")
       },
       {
         func: "compileTemplates",
-        selector: ({ selectByTag }) => selectByTag("template")
+        selector: state => state.selectByTag("template")
       },
       {
         func: "copy",
-        selector: ({ selectByTag }) => selectByTag("styles")
+        selector: state => state.selectByTag("styles")
       }
     ],
     [
       {
         func: "renderTemplate",
-        selector: ({ selectOne }) =>
-          selectOne(
+        selector: state =>
+          state.selectOne(
             item => item.tags.includes("markdown") && item.name === "cv"
           ),
-        getConfig: ({ selectByTag, selectOne }) => ({
+        getConfig: state => ({
           meta: {
-            styles: selectOne(item => item.name === "styles")
+            styles: state.selectOne(item => item.name === "styles")
           },
-          template: selectOne(
+          template: state.selectOne(
             item => item.tags.includes("template") && item.name === "template"
           )
         })
@@ -99,12 +99,12 @@ module.exports = {
     [
       {
         func: "writeOutFile",
-        selector: ({ selectMany }) => selectMany(item => true),
+        selector: state => state.selectMany(item => true),
         config: { outputDir: "./output" }
       },
       {
         func: "writeOutPDF",
-        selector: ({ selectMany }) => selectMany(item => true),
+        selector: state => state.selectMany(item => true),
         config: { outputDir: "./output" }
       }
     ]

+ 1 - 1
.npm-scripts/build.js

@@ -1,4 +1,4 @@
-const Grapefruit = require("grapefruit");
+const Grapefruit = require("../../grapefruit");
 const careless = require("careless-fs");
 const buildPipeline = require("./build-pipeline");
 const history = new Grapefruit.History();

+ 10 - 1
.npm-scripts/funcs/compileTemplates.js

@@ -1,11 +1,20 @@
 const Handlebars = require("handlebars");
 const handlebarsCompiler = Handlebars.compile;
 
-module.exports = function(config, item) {
+function compileTemplates(config, item) {
   return new Promise(function(resolve) {
     resolve({
       ...item,
       template: handlebarsCompiler(item.content)
     });
   });
+}
+compileTemplates.withConfig = function(config) {
+  if (config.partials) {
+    config.partials.map(partial =>
+      Handlebars.registerPartial(partial.name, partial.content)
+    );
+  }
+  return item => compileTemplates(config, item);
 };
+module.exports = compileTemplates;

+ 41 - 0
.npm-scripts/funcs/imageMin.js

@@ -0,0 +1,41 @@
+const imagemin = require("imagemin");
+const imageminSvgo = require("imagemin-svgo");
+const imageminJpegtran = require("imagemin-jpegtran");
+const imageminPngquant = require("imagemin-pngquant");
+const mkdirp = require("mkdirp");
+
+module.exports = function(config, item) {
+  return new Promise(function(resolve, reject) {
+    const destination = `${config.outputDir}/${item.outputDir}`;
+    mkdirp(destination, err => {
+      if (err) {
+        reject({
+          message: `could not create directory: ${destination}`,
+          ...err
+        });
+      }
+      imagemin([item.path], {
+        destination,
+        plugins: [
+          imageminSvgo({
+            plugins: [{ removeViewBox: false }]
+          }),
+          imageminJpegtran(),
+          imageminPngquant({
+            quality: [0.6, 0.8]
+          })
+        ]
+      })
+        .then(result => {
+          const newItem = {
+            ...item,
+            path: item.outputPath
+          };
+          resolve(newItem);
+        })
+        .catch(e => {
+          reject(e);
+        });
+    });
+  });
+};

+ 9 - 13
.npm-scripts/funcs/listDirectory.js

@@ -1,24 +1,20 @@
-const fsN = require("fs");
-const path = require("path");
+const recursive = require("recursive-readdir");
 
 module.exports = function(config, item) {
   return new Promise(function(resolve, reject) {
-    fsN.readdir(config.directory, { withFileTypes: true }, function(
-      err,
-      dirListing
-    ) {
+    recursive(config.directory, function(err, dirListing) {
       if (err) {
         reject(err);
       }
       resolve(
-        dirListing.reduce((filenames, fileDirent) => {
-          return fileDirent.isFile()
-            ? filenames.concat({
+        dirListing
+          ? dirListing.reduce((filenames, file) => {
+              return filenames.concat({
                 ...item,
-                path: path.join(config.directory, fileDirent.name)
-              })
-            : filenames;
-        }, [])
+                path: file
+              });
+            }, [])
+          : []
       );
     });
   });

+ 13 - 9
.npm-scripts/funcs/minifyHtml.js

@@ -2,14 +2,18 @@ const minify = require("html-minifier").minify;
 
 module.exports = function(config, item) {
   return new Promise(function(resolve, reject) {
-    resolve({
-      ...item,
-      content: minify(item.content, {
-        removeAttributeQuotes: true,
-        minifyCSS: true,
-        minifyJS: true,
-        collapseWhitespace: true
-      })
-    });
+    try {
+      resolve({
+        ...item,
+        content: minify(item.content, {
+          removeAttributeQuotes: true,
+          minifyCSS: true,
+          minifyJS: true,
+          collapseWhitespace: true
+        })
+      });
+    } catch (e) {
+      reject(e);
+    }
   });
 };

+ 1 - 0
.npm-scripts/funcs/readInFile.js

@@ -10,6 +10,7 @@ module.exports = function(config, item) {
         });
       })
       .catch(function(err) {
+        console.log("Err", err);
         reject(err);
       });
   });

+ 1 - 1
.npm-scripts/funcs/renderTemplate.js

@@ -16,7 +16,7 @@ module.exports = function(config, item) {
         content
       });
     } catch (e) {
-      reject({ message: "Could not render template", funcError: e });
+      reject(e);
     }
   });
 };

+ 20 - 0
.npm-scripts/funcs/rmrf.js

@@ -0,0 +1,20 @@
+const rimraf = require("rimraf");
+module.exports = function(config, item) {
+  return new Promise(function(resolve, reject) {
+    if (!config.unsafe && item.path.substring(0, 2) !== "./") {
+      reject({
+        message: `path \`${
+          item.path
+        }\` is not local to the project. If you're sure you want to do this, set config.unsafe to true.`,
+        item
+      });
+    }
+
+    rimraf(item.path, err => {
+      if (err) {
+        reject(err);
+      }
+      resolve({ ...item, path: null });
+    });
+  });
+};

+ 3 - 3
.npm-scripts/funcs/writeOutFile.js

@@ -1,7 +1,7 @@
-const fs = require("careless-fs");
+const fs = require("../../../careless-fs");
 module.exports = function(config, item) {
   return fs.write({
-    path: `${config.outputDir}/${item.outputPath}${item.outputExtension}`,
-    content: item.content
+    ...item,
+    path: `${config.outputDir}/${item.outputPath}${item.outputExtension}`
   });
 };

+ 1 - 0
.nvmrc

@@ -0,0 +1 @@
+lts/*

+ 26 - 5
cv.md

@@ -12,9 +12,11 @@ discuss these further, but for now I'll keep it brief.
 *2019*
 
 Worked on a high-profile project for a well-known international clothing brand,
-using React, Netlify, Next.js, AWS lambda, nodeJS and AWS dynamoDB. Working remotely as
-part of a small, internationally distributed team to deliver a time-critical
-project with many challenges and tight deadlines.
+using React, Netlify, Next.js, AWS lambda, nodeJS and AWS dynamoDB to deliver an
+integrated customer experience across in-store devices, mobile websites and a
+facebook messenger bot. Working remotely as part of a small, internationally 
+distributed team to deliver a time-critical project with many challenges and
+tight deadlines.
 
 ### Erlang Solutions - JavaScript consultant (9 months, fully remote)
 *2018 to 2019*
@@ -67,8 +69,9 @@ I've around 10 years experience with JavaScript, and consider myself
 proficient. I take an active interest in new developments, often spending my
 free time checking out new features and frameworks.
 
-* React, Redux, Apollo GraphQL
-* NodeJS
+* React (Redux/Apollo GraphQL/hooks/reselect)
+* API integration (analytics/Facebook messenger platform/payment systems/GraphQL)
+* NodeJS (Express/Restify/native HTTP/cloud functions)
 * Document DBs (Mongo/Couchbase/DynamoDB)
 * Client-side templating (Handlebars/Mustache/jst)
 * Module loading & dependency resolution
@@ -134,6 +137,24 @@ environments, with varying degrees of depth.
 * Erlang (Phoenix, moderate)
 * C# (.NET, moderate)
 
+### References/reviews
+
+#### AKQA - Mike Carlisle (Group Technical Director / Consultant / Architect)
+*October 2019* 
+
+> Craig worked with us on an extremely intense project with tight timelines. He was able to help deliver the project and put in additional effort above and beyond what was expected of him. He was able to ramp up quickly and own the solutions he worked on, as well as reacting to changing requirements and challenges. Craig worked closely with an external API team to overcome issues and deficiencies with data, and collaborate around improvements with how data was retrieved to optimize for performance. He also produced the frontend for a web experience in ReactJs to design specifications, and with impressive turn-around. Craig also owned and delivered a Facebook Messenger Bot as part of the solution.
+> 
+> This was an unusually challenging and stressful project, and we were lucky to
+> have Craig staying focused and committed to the delivery of the end experience.
+
+#### Erlang Solutions - Katarzyna Kraus (Project Manager)
+*June 2019* 
+
+> I had the pleasure of working with Craig on a few month long project implementing an Elixir based app. As our frontend expert he had an additional challenge being the only representative of his field on a distributed team of backend engineers. With members located all over Europe, taking on intertwined tasks, there was an additional requirement of communicating effectively within the team to make sure everyone progresses with their work and does not block others. The success hinged on developers actively coordinating with each other and keeping the conversation going. Craig’s friendly attitude, sense of humour and opened mind played a huge role in making that happen.
+> Craig managed to combine the requirements of being the sole expert in his field with being a team player aiding other people and overall team progress. He took initiative, was able to advise and guide the customer towards certain solutions, he listened to feedback and changing requirements and moved forward in a steady, confident pace. He is not the loudest voice in the room and not the one to initiate edgy endeavours, but his advice is well thought out, meaningful and opened for debate. He is not afraid to admit mistakes and raise flags if he thinks something is going wrong, which builds trust within the team and allows management to make good decisions.
+> It is my opinion Craig’s personality will match any team and combined with his expertise as a seasoned frontend developer will help projects reach a successful delivery.
+
+
 ## I'm not boring
 
 I have quite a few hobbies outside of my development work, and try to keep myself as active as I can - especially during the summer, when I can get outside.

+ 55 - 32
package-lock.json

@@ -79,10 +79,11 @@
       }
     },
     "careless-fs": {
-      "version": "1.0.3",
-      "resolved": "https://registry.npmjs.org/careless-fs/-/careless-fs-1.0.3.tgz",
-      "integrity": "sha512-tMj0HKbhMkVZ+nedgUxTShb4AtFSxBX62PyEuTsVKCNbI0rCOSIwBnwgctRmZq2pM/WfScliCmESOW7qb+5KCA==",
+      "version": "github:leakypixel/careless-fs#688c82b60c43459ec9b5aa7dc165f81522090e91",
+      "from": "github:leakypixel/careless-fs",
       "requires": {
+        "into-stream": "^5.1.1",
+        "is-stream": "^2.0.0",
         "mkdirp": "^0.5.1"
       }
     },
@@ -135,8 +136,7 @@
     "core-util-is": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
-      "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=",
-      "optional": true
+      "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac="
     },
     "dashdash": {
       "version": "1.14.1",
@@ -265,6 +265,15 @@
         "mime-types": "^2.1.12"
       }
     },
+    "from2": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz",
+      "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=",
+      "requires": {
+        "inherits": "^2.0.1",
+        "readable-stream": "^2.0.0"
+      }
+    },
     "fs-extra": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-1.0.0.tgz",
@@ -292,7 +301,7 @@
       "optional": true
     },
     "grapefruit": {
-      "version": "github:leakypixel/grapefruit#85a03f60c8ad3eaee9cc09e530fce01c66ead7fc",
+      "version": "github:leakypixel/grapefruit#aeb98b934c8a20397280c4480ff7c90b0e7ad6b8",
       "from": "github:leakypixel/grapefruit"
     },
     "handlebars": {
@@ -330,6 +339,14 @@
       "requires": {
         "is-stream": "^1.0.1",
         "pinkie-promise": "^2.0.0"
+      },
+      "dependencies": {
+        "is-stream": {
+          "version": "1.1.0",
+          "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
+          "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=",
+          "optional": true
+        }
       }
     },
     "he": {
@@ -396,14 +413,21 @@
     "inherits": {
       "version": "2.0.4",
       "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
-      "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
-      "optional": true
+      "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
+    },
+    "into-stream": {
+      "version": "5.1.1",
+      "resolved": "https://registry.npmjs.org/into-stream/-/into-stream-5.1.1.tgz",
+      "integrity": "sha512-krrAJ7McQxGGmvaYbB7Q1mcA+cRwg9Ij2RfWIeVesNBgVDZmzY/Fa4IpZUT3bmdRzMzdf/mzltCG2Dq99IZGBA==",
+      "requires": {
+        "from2": "^2.3.0",
+        "p-is-promise": "^3.0.0"
+      }
     },
     "is-stream": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
-      "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=",
-      "optional": true
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz",
+      "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw=="
     },
     "is-typedarray": {
       "version": "1.0.0",
@@ -414,8 +438,7 @@
     "isarray": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
-      "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
-      "optional": true
+      "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
     },
     "isexe": {
       "version": "2.0.0",
@@ -508,18 +531,18 @@
       "integrity": "sha512-LRxmNwziLPT828z+4YkNzloCFC2YM4wrB99k+AV5ZbEyfGNWfG8SO1FUXLmLDBSo89NrJZ4DIWeLjy1CHGhMGA=="
     },
     "mime-db": {
-      "version": "1.40.0",
-      "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz",
-      "integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA==",
+      "version": "1.42.0",
+      "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.42.0.tgz",
+      "integrity": "sha512-UbfJCR4UAVRNgMpfImz05smAXK7+c+ZntjaA26ANtkXLlOe947Aag5zdIcKQULAiF9Cq4WxBi9jUs5zkA84bYQ==",
       "optional": true
     },
     "mime-types": {
-      "version": "2.1.24",
-      "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz",
-      "integrity": "sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==",
+      "version": "2.1.25",
+      "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.25.tgz",
+      "integrity": "sha512-5KhStqB5xpTAeGqKBAMgwaYMnQik7teQN4IAzC7npDv6kzeU6prfkR67bc87J1kWMPGkoaZSq1npmexMgkmEVg==",
       "optional": true,
       "requires": {
-        "mime-db": "1.40.0"
+        "mime-db": "1.42.0"
       }
     },
     "minimist": {
@@ -585,6 +608,11 @@
         "wordwrap": "~0.0.2"
       }
     },
+    "p-is-promise": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-3.0.0.tgz",
+      "integrity": "sha512-Wo8VsW4IRQSKVXsJCn7TomUaVtyfjVDn3nUP7kE967BQk0CwFpdbZs0X0uk5sW9mkBa9eNM7hCMaG93WUAwxYQ=="
+    },
     "param-case": {
       "version": "2.1.1",
       "resolved": "https://registry.npmjs.org/param-case/-/param-case-2.1.1.tgz",
@@ -640,8 +668,7 @@
     "process-nextick-args": {
       "version": "2.0.1",
       "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
-      "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==",
-      "optional": true
+      "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag=="
     },
     "progress": {
       "version": "1.1.8",
@@ -671,7 +698,6 @@
       "version": "2.3.6",
       "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
       "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
-      "optional": true,
       "requires": {
         "core-util-is": "~1.0.0",
         "inherits": "~2.0.3",
@@ -727,8 +753,7 @@
     "safe-buffer": {
       "version": "5.1.2",
       "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
-      "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
-      "optional": true
+      "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
     },
     "safer-buffer": {
       "version": "2.1.2",
@@ -762,7 +787,6 @@
       "version": "1.1.1",
       "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
       "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
-      "optional": true,
       "requires": {
         "safe-buffer": "~5.1.0"
       }
@@ -813,9 +837,9 @@
       "optional": true
     },
     "uglify-js": {
-      "version": "3.6.8",
-      "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.6.8.tgz",
-      "integrity": "sha512-XhHJ3S3ZyMwP8kY1Gkugqx3CJh2C3O0y8NPiSxtm1tyD/pktLAkFZsFGpuNfTZddKDQ/bbDBLAd2YyA1pbi8HQ==",
+      "version": "3.6.9",
+      "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.6.9.tgz",
+      "integrity": "sha512-pcnnhaoG6RtrvHJ1dFncAe8Od6Nuy30oaJ82ts6//sGSXOP5UjBMEthiProjXmMNHOfd93sqlkztifFMcb+4yw==",
       "optional": true,
       "requires": {
         "commander": "~2.20.3",
@@ -844,8 +868,7 @@
     "util-deprecate": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
-      "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=",
-      "optional": true
+      "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8="
     },
     "uuid": {
       "version": "3.3.3",

+ 1 - 1
package.json

@@ -15,7 +15,7 @@
     "url": "https://git.lpapi.io/leakypixel/cv/issues"
   },
   "dependencies": {
-    "careless-fs": "^1.0.0",
+    "careless-fs": "github:leakypixel/careless-fs",
     "ecstatic": "^4.1.2",
     "grapefruit": "github:leakypixel/grapefruit",
     "handlebars": "^4.0.12",

+ 30 - 22
styles.css

@@ -1,19 +1,7 @@
-/* Reset a couple of things for the sake of ease */
-/* Variables */
-:root {
-  --color-background: #f0f0f0;
-  --color-background-alternative: #afafaf;
-  --color-text-default: #0e0e0e;
-  --color-accent-1: #0000ff;
-  --color-accent-2: #00ff00;
-  --color-accent-3: #ff0000;
-}
-/* End variables */
-
 /* General styles */
 body {
-  background-color: var(--color-background);
-  color: var(--color-text-default);
+  background-color: #f0f0f0;
+  color: #0e0e0e;
   line-height: 1.6em;
   letter-spacing: 0.025em;
   font-family: "Noto sans", sans-serif;
@@ -43,9 +31,8 @@ h1 {
   letter-spacing: 0.025em;
   font-size: 2.6em;
   line-height: 1.6em;
-  border-bottom: 0.4em solid;
-  border-color: var(--color-accent-2);
   margin: 1em 0 2em 0;
+  box-shadow: inset 0 -1.4rem 0 #00ff00;
 }
 
 h2 {
@@ -61,7 +48,7 @@ h2 {
 }
 
 h3 {
-  color: var(--color-text-alternative);
+  color: #4f4f4f;
   font-family: "Gidole", monospace;
   text-transform: uppercase;
   font-weight: 400;
@@ -69,11 +56,20 @@ h3 {
   margin: 4em 0 1em 0;
 }
 
+h4 {
+  color: #4f4f4f;
+  font-family: "Gidole", monospace;
+  text-transform: uppercase;
+  font-weight: 400;
+  font-size: 1em;
+  margin: 4em 0 1em 0;
+}
+
 a,
 a:active,
 a:visited {
-  background-color: var(--color-accent-1);
-  color: var(--color-background);
+  background-color: #0000ff;
+  color: #f0f0f0;
   text-decoration: underline;
   padding: 0 0.2em;
 }
@@ -82,17 +78,26 @@ p {
   font-size: 1.2em;
   line-height: 1.75em;
   margin: 1em 0;
+  break-inside: avoid;
 }
 
 em {
   font-size: 0.8em;
 }
 
+ul {
+  break-inside: avoid;
+}
+
 li {
   margin: 1em 0;
   padding-left: 0.8em;
 }
 
+blockquote {
+  font-size: 0.8em;
+}
+
 /* Header */
 header {
   margin: 1em auto 4em auto;
@@ -131,15 +136,18 @@ header {
 }
 
 @media print {
+  p {
+    break-inside: avoid;
+  }
   section {
-    max-width: 100%;
-    width: 100%;
+    max-width: 95%;
+    width: 95%;
     margin: 0;
   }
   body {
     max-width: 95%;
     width: 95%;
-    margin: 1em;
+    margin: 2em;
     font-size: 14px;
   }
 }