diff --git a/.gitignore b/.gitignore
index 6a2cb2d..b87cd7e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,5 +1,7 @@
+*.backup
 app/
 data/
+__nightdocs/
 # Created by https://www.gitignore.io/api/git
 # Edit at https://www.gitignore.io/?templates=git
 
diff --git a/README.md b/README.md
index ff06edd..f79cabe 100644
--- a/README.md
+++ b/README.md
@@ -11,219 +11,6 @@ The client-side browser application is powered by [Leaflet](https://leafletjs.co
 
 Note that this project is _not_ responsible for entering data into the database. This project's purpose is simply to display the data.
 
-## System Requirements
-In order to run this program, you'll need the following:
-
- - Git
- - Bash (if on Windows, try [Git Bash](https://gitforwindows.org/)) - the build script is written in Bash
- - [composer](https://getcomposer.org/) - For the server-side packages
- - [Node.JS](https://nodejs.org/)
- - [npm](https://npmjs.org/) - comes with Node.JS - used for building the client-side code
- - A [MariaDB](https://mariadb.com/) server with a database already setup with the schema data in it. Please get in contact with [ConnectedHumber](https://connectedhumber.org/) for information about the database schema and structure.
-
-## Getting Started
-The client-side code requires building. Currently, no pre-built versions are available (though these can be provided upon request), so this must be done from source. A build script is available, however, which automates the process - as explained below.
-
-### System Requirements
- - PHP-enabled web server
-     - _Nginx_ + _PHP-FPM_ is recommended
-     - Apache works too
- - MariaDB database with the appropriate table structure pre-loaded
- - PHP 7+
- - Node.JS (preferably 10+) + npm 6+ (for installing & building the client-side app code)
- - [Composer](https://getcomposer.org/) (for installing server-side dependencies)
- - PHP modules:
-     - `pdo-mysql` (for the database connection)
-
-### Installation
-1. Start by cloning this repository:
-
-```bash
-git clone https://github.com/ConnectedHumber/Air-Quality-Web.git
-```
-
-
-2. `cd` into the root of the cloned repository. Then install the dependencies (these are installed locally):
-
-```bash
-./build setup setup-dev
-```
-
-
-3. Build the client-side application:
-
-```bash
-# For development, run this:
-./build client
-# For production, run this:
-NODE_ENV=production ./build client
-# If you're actively working on the codebase and need to auto-recompile on every change, run this:
-./build client-watch
-```
-
-4. Change the ownership to allow your web server user to access the created directory. Usually, the web server will be running under the `www-data` user:
-
-```bash
-sudo chown -R www-data:www-data path/to/Air-Quality-Web
-```
-
-
-5. Edit `data/settings.toml` to enter your database credentials.
-
-You can edit other settings here too. See `settings.default.toml` for the settings you can change, but do **not** edit `settings.default.toml`! Edit `data/settings.toml` instead. You'll probably want to give the entire default settings file a careful read.
-
-
-6. Configure your web server to serve the root of the repository you've cloned if you haven't already. Skip this step if you cloned the repository into a directory that your web server already serves.
-
-
-7. Disallow public access to the private `data`  directory.
-
-In Nginx:
-
-```nginx
-# Put this inside the "server {  }" website definition block:
-# The "server {  }" block can usually be found somewhere in /etc/nginx on Linux machines, and may have a "server_name" directive specifying the domain name it's serving if multiple websites are configured.
-location ^~ /path/to/data/directory {
-    deny all;
-}
-```
-
-In Apache:
-
-```htaccess
-# Create a file called ".htaccess" with this content inside the data/ directory
-Require all denied
-```
-
-
-8. Test the application with an API call. If this returns valid JSON, then you've set it up correctly
-
-```
-http://example.com/path/to/Air-Quality-Web/api.php?action=list-devices
-```
-
-
-9. (Optional) Setup HTTPS:
-
-```bash
-sudo apt install certbot
-# On Nginx:
-sudo certbot --nginx --domain example.com
-# On Apache:
-sudo certbot --apache --domain example.com
-```
-
-
-## API
-The server-side API is accessed through `api.php`, and supports a number of GET parameters. The most important of these is the `action` parameter, Which determines what the API will do. The following values are supported:
-
-### version
-> Returns the version of the application.
-
-_No parameters are currently supported by this action._
-
-Examples:
-
-
-```
-https://example.com/path/to/api.php?action=version
-```
-
-
-### fetch-data
-> Fetches air quality data from the system for a specific data type at a specific date and time.
-
-Parameter			| Type		| Meaning
---------------------|-----------|---------------------
-`datetime`			| date/time	| Required. Specifies the date and time for which readings are desired. For current data use the special keyword `now`.
-`reading_type`		| string	| Required. Specifies the type of reading desired.
-`format`            | string    | Optional. Specifies the format that the response will be returned in. Valid values: `json`, `csv`. Default: `json`.
-
-Examples:
-
-```
-https://example.com/path/to/api.php?action=fetch-data&datetime=2019-01-03%2007:52:10&reading_type=PM10
-https://example.com/path/to/api.php?action=fetch-data&datetime=now&reading_type=PM10
-```
-
-### list-devices
-> Fetches a list of devices currently in the system.
-
-Parameter			| Type		| Meaning
---------------------|-----------|---------------------
-`only-with-location`| bool		| Optional. If present only devices with a defined location will be returned. Useful for getting a list of devices to place on a map.
-`format`            | string    | Optional. Specifies the format that the response will be returned in. Valid values: `json`, `csv`. Default: `json`.
-
-Examples:
-
-```
-https://example.com/path/to/api.php?action=list-devices
-https://example.com/path/to/api.php?action=list-devices&only-with-location=yes
-```
-
-### device-info
-> Gets (lots of) information about a single device.
-
-Parameter			| Type		| Meaning
---------------------|-----------|---------------------
-`device-id`         | int		| Required. The id of the device to get extended information for. See the `list-device` action for how to get a hold of one.
-
-Examples:
-
-### list-reading-types
-> Lists the different types of readings that can be specified.
-
-Parameter			| Type		| Meaning
---------------------|-----------|---------------------
-`device-id`         | int		| Optional. If specified, this filters the list of measurement types to list only those reported by the device with the specified id.
-`format`            | string    | Optional. Specifies the format that the response will be returned in. Valid values: `json`, `csv`. Default: `json`.
-
-```
-https://example.com/path/to/api.php?action=list-reading-types
-https://example.com/path/to/api.php?action=list-reading-types&device-id=22
-https://example.com/path/to/api.php?action=list-reading-types&device-id=54
-```
-
-
-### device-data-bounds
-> Gets the start and end DateTime bounds for the data recorded for a specific device.
-
-Parameter			| Type		| Meaning
---------------------|-----------|---------------------
-`device-id`         | int		| Required. The id of the device to get the data DateTime bounds for.
-
-```
-https://example.com/path/to/api.php?action=device-data-bounds&device-id=18
-https://example.com/path/to/api.php?action=device-data-bounds&device-id=11
-```
-
-### device-data
-> Gets data by device given a start and end time.
-
-Parameter			| Type		| Meaning
---------------------|-----------|---------------------
-`device-id`			| int		| The id of the device to get data for.
-`reading-type`		| string	| The type of reading to obtain data for.
-`start`				| datetime  | The starting datetime.
-`end`				| datetime  | The ending datetime.
-`average-seconds`	| int		| Optional. If specified, readings will be grouped into lumps of this many seconds and averaged. For example a value of 3600 (1 hour) will return 1 data point per hour, with the value of each point an average of all the readings for that hour.
-`format`            | string    | Optional. Specifies the format that the response will be returned in. Valid values: `json`, `csv`. Default: `json`.
-
-```
-https://example.com/path/to/api.php?action=device-data&device-id=18&reading-type=PM25&start=2019-01-19T18:14:59.992Z&end=2019-01-20T18:14:59.992Z
-https://example.com/path/to/api.php?action=device-data&device-id=18&reading-type=PM25&start=2019-01-19T18:14:59.992Z&end=2019-01-20T18:14:59.992Z&average-seconds=3600
-https://example.com/path/to/api.php?action=device-data&device-id=18&reading-type=PM25&start=2019-01-19T18:14:59.992Z&end=now&average-seconds=3600&format=csv
-```
-
-
-### changelog
-> Gets the changelog as a fragment of HTML.
-
-_No parameters are currently supported by this action._
-
-```
-https://example.com/path/to/api.php?action=changelog
-```
 
 
 ## Notes
diff --git a/build b/build
index 0e8e44b..004c91a 100755
--- a/build
+++ b/build
@@ -54,7 +54,9 @@ if [[ "$#" -lt 1 ]]; then
 	echo -e "    ${CACTION}dev-server${RS}       - Start a development server";
 	echo -e "    ${CACTION}dev-server-stop${RS}  - Stop the currently running development server";
 	echo -e "    ${CACTION}client${RS}           - Build the client web app";
-	echo -e "    ${CACTION}client-watch${RS} - Watch for changes to the client code & rebuild automatically";
+	echo -e "    ${CACTION}client-watch${RS}     - Watch for changes to the client code & rebuild automatically";
+	echo -e "    ${CACTION}docs${RS}             - Render the documentation";
+	echo -e "    ${CACTION}ci${RS}               - Perform CI tasks";
 	echo -e "";
 	
 	exit 1;
@@ -62,7 +64,15 @@ fi
 
 ###############################################################################
 
-function task_setup {
+
+
+# ███████ ███████ ████████ ██    ██ ██████
+# ██      ██         ██    ██    ██ ██   ██
+# ███████ █████      ██    ██    ██ ██████
+#      ██ ██         ██    ██    ██ ██
+# ███████ ███████    ██     ██████  ██
+
+task_setup() {
 	stage_begin "Setting up";
 	
 	task_begin "Checking environment";
@@ -112,7 +122,7 @@ function task_setup {
 	stage_end $?;
 }
 
-function task_setup-dev {
+task_setup-dev() {
 	task_begin "Checking environment";
 	check_command mysql true optional;
 	task_end $?;
@@ -126,7 +136,14 @@ function task_setup-dev {
 	task_end $?;
 }
 
-function task_database {
+
+# ██████  ███████ ██    ██
+# ██   ██ ██      ██    ██
+# ██   ██ █████   ██    ██
+# ██   ██ ██       ██  ██
+# ██████  ███████   ████
+
+task_database() {
 	task_begin "Connecting to the database";
 	set-title "Database";
 	ssh -TN "${database_host}" -L 3306:localhost:3306 &
@@ -138,7 +155,7 @@ function task_database {
 	task_end $?;
 }
 
-function task_dev-server {
+task_dev-server() {
 	task_begin "Starting development server";
 	php -S [::1]:40482 &
 	exit_code=$?;
@@ -147,7 +164,7 @@ function task_dev-server {
 	sleep 1;
 }
 
-function task_dev-server-stop {
+task_dev-server-stop() {
 	task_begin "Stopping development server";
 	
 	kill "$(cat /tmp/micro-lantern-dev-server.pid)";
@@ -157,7 +174,13 @@ function task_dev-server-stop {
 }
 
 
-function task_client {
+#  ██████ ██      ██ ███████ ███    ██ ████████
+# ██      ██      ██ ██      ████   ██    ██
+# ██      ██      ██ █████   ██ ██  ██    ██
+# ██      ██      ██ ██      ██  ██ ██    ██
+#  ██████ ███████ ██ ███████ ██   ████    ██
+
+task_client() {
 	task_begin "Packaging Javascript";
 	node_modules/rollup/bin/rollup --sourcemap --config rollup.config.js;
 	task_end $? "Error: rollup packing failed!";
@@ -172,7 +195,7 @@ function task_client {
 	# task_end $?;
 }
 
-function task_client-watch {
+task_client-watch() {
 	set-title "Client Watcher";
 	
 	echo -e "Watching for changes.";
@@ -189,6 +212,30 @@ function task_client-watch {
 	done
 }
 
+
+# ██████   ██████   ██████ ███████
+# ██   ██ ██    ██ ██      ██
+# ██   ██ ██    ██ ██      ███████
+# ██   ██ ██    ██ ██           ██
+# ██████   ██████   ██████ ███████
+
+task_docs() {
+	task_begin "Rendering docs";
+	node_modules/.bin/nightdocs --config nightdocs.toml;
+	task_end $?;
+}
+
+
+#  ██████ ██
+# ██      ██
+# ██      ██
+# ██      ██
+#  ██████ ██
+task_ci() {
+	tasks_run setup setup-dev client docs;
+}
+
+
 #########################################################################
 
 tasks_run $@;
diff --git a/docs/00-Welcome.md b/docs/00-Welcome.md
new file mode 100644
index 0000000..5a7d5e9
--- /dev/null
+++ b/docs/00-Welcome.md
@@ -0,0 +1,7 @@
+# Welcome!
+
+> The Web Interface for the _Monitair_ project.
+
+This is the documentation for [Air Quality Web](https://github.com/ConnectedHumber/Air-Quality-Web/), the air quality web interface that displays data from sensors scattered about the globe.
+
+Check out the sections in the sidebar for documentation on the installation process, configuring an installation, and the HTTP API provided.
diff --git a/docs/01-Getting-Started.md b/docs/01-Getting-Started.md
new file mode 100644
index 0000000..4d6b68e
--- /dev/null
+++ b/docs/01-Getting-Started.md
@@ -0,0 +1,102 @@
+# Getting Started
+To get started, there are 3 main steps:
+
+1. Cloning & building the application
+2. Configuring the application
+3. Configuration a web server
+
+The process is outlined in detail below.
+
+
+## System Requirements
+ - Git
+ - Bash (if on Windows, try [Git Bash](https://gitforwindows.org/)) - the build script is written in Bash
+ - PHP 7+ enabled web server
+     - _Nginx_ + _PHP-FPM_ is recommended
+     - Apache works too
+ - MariaDB database with the appropriate table structure pre-loaded
+ - Node.JS (preferably 10+) + [npm](https://npmjs.org/) 6+ (for installing & building the client-side app code)
+ - [Node.JS](https://nodejs.org/)
+ - [Composer](https://getcomposer.org/) (for installing server-side dependencies)
+ - PHP modules:
+     - `pdo-mysql` (for the database connection)
+ - A [MariaDB](https://mariadb.com/) server with a database already setup with the schema data in it. Please get in contact with [ConnectedHumber](https://connectedhumber.org/) for information about the database schema and structure.
+
+
+## Installation
+1. Start by cloning this repository:
+
+```bash
+git clone https://github.com/ConnectedHumber/Air-Quality-Web.git
+```
+
+
+2. `cd` into the root of the cloned repository. Then install the dependencies (these are installed locally):
+
+```bash
+./build setup setup-dev
+```
+
+
+3. Build the client-side application:
+
+```bash
+# For development, run this:
+./build client
+# For production, run this:
+NODE_ENV=production ./build client
+# If you're actively working on the codebase and need to auto-recompile on every change, run this:
+./build client-watch
+```
+
+4. Change the ownership to allow your web server user to access the created directory. Usually, the web server will be running under the `www-data` user:
+
+```bash
+sudo chown -R www-data:www-data path/to/Air-Quality-Web
+```
+
+
+5. Edit `data/settings.toml` to enter your database credentials.
+
+You can edit other settings here too. See `settings.default.toml` for the settings you can change, but do **not** edit `settings.default.toml`! Edit `data/settings.toml` instead. You'll probably want to give the entire default settings file a careful read.
+
+
+6. Configure your web server to serve the root of the repository you've cloned if you haven't already. Skip this step if you cloned the repository into a directory that your web server already serves.
+
+
+7. Disallow public access to the private `data`  directory.
+
+In Nginx:
+
+```nginx
+# Put this inside the "server {  }" website definition block:
+# The "server {  }" block can usually be found somewhere in /etc/nginx on Linux machines, and may have a "server_name" directive specifying the domain name it's serving if multiple websites are configured.
+location ^~ /path/to/data/directory {
+    deny all;
+}
+```
+
+In Apache:
+
+```htaccess
+# Create a file called ".htaccess" with this content inside the data/ directory
+Require all denied
+```
+
+
+8. Test the application with an API call. If this returns valid JSON, then you've set it up correctly
+
+```
+http://example.com/path/to/Air-Quality-Web/api.php?action=list-devices
+```
+
+
+9. (Optional) Setup HTTPS:
+
+```bash
+sudo apt install certbot
+# On Nginx:
+sudo certbot --nginx --domain example.com
+# On Apache:
+sudo certbot --apache --domain example.com
+```
diff --git a/docs/05-API-Docs.md b/docs/05-API-Docs.md
new file mode 100644
index 0000000..0b792bf
--- /dev/null
+++ b/docs/05-API-Docs.md
@@ -0,0 +1,110 @@
+# API
+The server-side API is accessed through `api.php`, and supports a number of GET parameters. The most important of these is the `action` parameter, Which determines what the API will do. The following values are supported:
+
+## version
+> Returns the version of the application.
+
+_No parameters are currently supported by this action._
+
+Examples:
+
+
+```
+https://example.com/path/to/api.php?action=version
+```
+
+
+## fetch-data
+> Fetches air quality data from the system for a specific data type at a specific date and time.
+
+Parameter			| Type		| Meaning
+--------------------|-----------|---------------------
+`datetime`			| date/time	| Required. Specifies the date and time for which readings are desired. For current data use the special keyword `now`.
+`reading_type`		| string	| Required. Specifies the type of reading desired.
+`format`            | string    | Optional. Specifies the format that the response will be returned in. Valid values: `json`, `csv`. Default: `json`.
+
+Examples:
+
+```
+https://example.com/path/to/api.php?action=fetch-data&datetime=2019-01-03%2007:52:10&reading_type=PM10
+https://example.com/path/to/api.php?action=fetch-data&datetime=now&reading_type=PM10
+```
+
+## list-devices
+> Fetches a list of devices currently in the system.
+
+Parameter			| Type		| Meaning
+--------------------|-----------|---------------------
+`only-with-location`| bool		| Optional. If present only devices with a defined location will be returned. Useful for getting a list of devices to place on a map.
+`format`            | string    | Optional. Specifies the format that the response will be returned in. Valid values: `json`, `csv`. Default: `json`.
+
+Examples:
+
+```
+https://example.com/path/to/api.php?action=list-devices
+https://example.com/path/to/api.php?action=list-devices&only-with-location=yes
+```
+
+## device-info
+> Gets (lots of) information about a single device.
+
+Parameter			| Type		| Meaning
+--------------------|-----------|---------------------
+`device-id`         | int		| Required. The id of the device to get extended information for. See the `list-device` action for how to get a hold of one.
+
+Examples:
+
+## list-reading-types
+> Lists the different types of readings that can be specified.
+
+Parameter			| Type		| Meaning
+--------------------|-----------|---------------------
+`device-id`         | int		| Optional. If specified, this filters the list of measurement types to list only those reported by the device with the specified id.
+`format`            | string    | Optional. Specifies the format that the response will be returned in. Valid values: `json`, `csv`. Default: `json`.
+
+```
+https://example.com/path/to/api.php?action=list-reading-types
+https://example.com/path/to/api.php?action=list-reading-types&device-id=22
+https://example.com/path/to/api.php?action=list-reading-types&device-id=54
+```
+
+
+## device-data-bounds
+> Gets the start and end DateTime bounds for the data recorded for a specific device.
+
+Parameter			| Type		| Meaning
+--------------------|-----------|---------------------
+`device-id`         | int		| Required. The id of the device to get the data DateTime bounds for.
+
+```
+https://example.com/path/to/api.php?action=device-data-bounds&device-id=18
+https://example.com/path/to/api.php?action=device-data-bounds&device-id=11
+```
+
+## device-data
+> Gets data by device given a start and end time.
+
+Parameter			| Type		| Meaning
+--------------------|-----------|---------------------
+`device-id`			| int		| The id of the device to get data for.
+`reading-type`		| string	| The type of reading to obtain data for.
+`start`				| datetime  | The starting datetime.
+`end`				| datetime  | The ending datetime.
+`average-seconds`	| int		| Optional. If specified, readings will be grouped into lumps of this many seconds and averaged. For example a value of 3600 (1 hour) will return 1 data point per hour, with the value of each point an average of all the readings for that hour.
+`format`            | string    | Optional. Specifies the format that the response will be returned in. Valid values: `json`, `csv`. Default: `json`.
+
+```
+https://example.com/path/to/api.php?action=device-data&device-id=18&reading-type=PM25&start=2019-01-19T18:14:59.992Z&end=2019-01-20T18:14:59.992Z
+https://example.com/path/to/api.php?action=device-data&device-id=18&reading-type=PM25&start=2019-01-19T18:14:59.992Z&end=2019-01-20T18:14:59.992Z&average-seconds=3600
+https://example.com/path/to/api.php?action=device-data&device-id=18&reading-type=PM25&start=2019-01-19T18:14:59.992Z&end=now&average-seconds=3600&format=csv
+```
+
+
+## changelog
+> Gets the changelog as a fragment of HTML.
+
+_No parameters are currently supported by this action._
+
+```
+https://example.com/path/to/api.php?action=changelog
+```
diff --git a/docs/README.md b/docs/README.md
new file mode 100644
index 0000000..ac13711
--- /dev/null
+++ b/docs/README.md
@@ -0,0 +1,7 @@
+# Air Quality Web
+
+ * [Welcome!](./00-Welcome.md)
+ * [Production Instance](https://aq.connectedhumber.org/app/)
+ * [Getting Started](01-Getting-Started.md)
+ * [Changelog](https://github.com/ConnectedHumber/Air-Quality-Web/blob/master/Changelog.md#changelog)
+ * [API Docs](05-API-Docs.md)
diff --git a/docs/theme.css b/docs/theme.css
new file mode 100644
index 0000000..e69de29
diff --git a/nightdocs.toml b/nightdocs.toml
new file mode 100644
index 0000000..e2e9056
--- /dev/null
+++ b/nightdocs.toml
@@ -0,0 +1,2 @@
+[template]
+project_name = "Air Quality Web Docs"
diff --git a/package-lock.json b/package-lock.json
index 7d56e19..f31dd91 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -144,6 +144,12 @@
       "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==",
       "dev": true
     },
+    "await-fs": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/await-fs/-/await-fs-1.0.0.tgz",
+      "integrity": "sha1-QAnTAIYz/WYlqgCfCm8aujY38wE=",
+      "dev": true
+    },
     "base": {
       "version": "0.11.2",
       "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz",
@@ -1406,6 +1412,12 @@
       "integrity": "sha512-P+M65QY2JQ5Y0G9KKdlDpo0zK+/OHptU5AaBwUfAIDJZk1MYf32Frm84EcOytfJE0t5JvkAnKlmjsXDnWzCJmQ==",
       "dev": true
     },
+    "html-entities": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-1.2.1.tgz",
+      "integrity": "sha1-DfKTUfByEWNRXfueVUPl9u7VFi8=",
+      "dev": true
+    },
     "icss-replace-symbols": {
       "version": "1.1.0",
       "resolved": "https://registry.npmjs.org/icss-replace-symbols/-/icss-replace-symbols-1.1.0.tgz",
@@ -1805,6 +1817,12 @@
         "object-visit": "^1.0.0"
       }
     },
+    "marked": {
+      "version": "0.6.1",
+      "resolved": "https://registry.npmjs.org/marked/-/marked-0.6.1.tgz",
+      "integrity": "sha512-+H0L3ibcWhAZE02SKMqmvYsErLo4EAVJxu5h3bHBBDvvjeWXtl92rGUSBYHL2++5Y+RSNgl8dYOAXcYe7lp1fA==",
+      "dev": true
+    },
     "mdn-data": {
       "version": "1.1.4",
       "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-1.1.4.tgz",
@@ -1949,6 +1967,27 @@
       "resolved": "https://registry.npmjs.org/nanomodal/-/nanomodal-5.1.1.tgz",
       "integrity": "sha1-qiEiUSr49vpr3G8y1nqm3whvfK0="
     },
+    "nightdocs": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/nightdocs/-/nightdocs-1.0.1.tgz",
+      "integrity": "sha512-JRX8iOjvW0wbYFNWH16deb8KFAQq9lM74IBT1SdtEjAyqetDs3DmsAsJNc/HRqft8QRcRDQmWsWeLbV4nrW0QQ==",
+      "dev": true,
+      "requires": {
+        "marked": "^0.6.1",
+        "nightink": "^0.1.2",
+        "toml": "^3.0.0"
+      }
+    },
+    "nightink": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npmjs.org/nightink/-/nightink-0.1.2.tgz",
+      "integrity": "sha512-nAyyf1EvghaFtmwD4ox2rFiY0eWqAsW6rulIPaPC5IMv3YaNKYdQ4F7zUZ6E7eONEVQGtiCGTv6YksY9wHHs1g==",
+      "dev": true,
+      "requires": {
+        "await-fs": "^1.0.0",
+        "html-entities": "^1.2.1"
+      }
+    },
     "node-releases": {
       "version": "1.1.10",
       "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.10.tgz",
@@ -4210,6 +4249,12 @@
         }
       }
     },
+    "toml": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/toml/-/toml-3.0.0.tgz",
+      "integrity": "sha512-y/mWCZinnvxjTKYhJ+pYxwD0mRLVvOtdS2Awbgxln6iEnt4rk0yBxeSBHkGJcPucRiG0e55mwWp+g/05rsrd6w==",
+      "dev": true
+    },
     "union-value": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.0.tgz",
diff --git a/package.json b/package.json
index 9f01596..40a2e04 100644
--- a/package.json
+++ b/package.json
@@ -1,45 +1,55 @@
 {
-  "name": "air-quality-mapper",
-  "version": "0.1.0",
-  "description": "The web interface and JSON api for the ConnectedHumber Air Quality Monitoring Project.",
-  "main": "index.mjs",
-  "scripts": {
-    "test": "echo \"Error: no test specified\" && exit 1"
-  },
-  "repository": {
-    "type": "git",
-    "url": "git+https://github.com/sbrl/ConnectedHumber-Air-Quality-Interface.git"
-  },
-  "author": "Starbeamrainbowlabs",
-  "license": "MPL-2.0",
-  "bugs": {
-    "url": "https://github.com/sbrl/ConnectedHumber-Air-Quality-Interface/issues"
-  },
-  "homepage": "https://github.com/sbrl/ConnectedHumber-Air-Quality-Interface#readme",
-  "dependencies": {
-    "chart.js": "^2.7.3",
-    "dom-create-element-query-selector": "github:hekigan/dom-create-element-query-selector",
-    "leaflet": "^1.4.0",
-    "leaflet-fullscreen": "^1.0.2",
-    "leaflet-timedimension": "^1.1.0",
-    "leaflet.markercluster": "^1.4.1",
-    "moment": "^2.24.0",
-    "nanomodal": "^5.1.1",
-    "smartsettings": "^1.2.3",
-    "tabs": "^0.2.0"
-  },
-  "devDependencies": {
-    "@types/chart.js": "^2.7.48",
-    "@types/leaflet": "^1.4.3",
-    "@types/leaflet-fullscreen": "^1.0.4",
-    "leaflet-heatmap": "^1.0.0",
-    "postcss-copy": "^7.1.0",
-    "postcss-import": "^12.0.1",
-    "rollup": "^1.6.0",
-    "rollup-plugin-commonjs": "^9.2.1",
-    "rollup-plugin-node-resolve": "^4.0.1",
-    "rollup-plugin-postcss": "^2.0.3",
-    "rollup-plugin-replace": "^2.1.0",
-    "rollup-plugin-terser": "^4.0.4"
-  }
+	"name": "air-quality-mapper",
+	"version": "0.1.0",
+	"description": "The web interface and JSON api for the ConnectedHumber Air Quality Monitoring Project.",
+	"main": "index.mjs",
+	"scripts": {
+		"test": "echo \"Error: no test specified\" && exit 1"
+	},
+	"repository": {
+		"type": "git",
+		"url": "git+https://github.com/sbrl/ConnectedHumber-Air-Quality-Interface.git"
+	},
+	"author": "Starbeamrainbowlabs",
+	"license": "MPL-2.0",
+	"bugs": {
+		"url": "https://github.com/sbrl/ConnectedHumber-Air-Quality-Interface/issues"
+	},
+	"homepage": "https://github.com/sbrl/ConnectedHumber-Air-Quality-Interface#readme",
+	"dependencies": {
+		"chart.js": "^2.7.3",
+		"dom-create-element-query-selector": "github:hekigan/dom-create-element-query-selector",
+		"leaflet": "^1.4.0",
+		"leaflet-fullscreen": "^1.0.2",
+		"leaflet-timedimension": "^1.1.0",
+		"leaflet.markercluster": "^1.4.1",
+		"moment": "^2.24.0",
+		"nanomodal": "^5.1.1",
+		"smartsettings": "^1.2.3",
+		"tabs": "^0.2.0"
+	},
+	"devDependencies": {
+		"@types/chart.js": "^2.7.48",
+		"@types/leaflet": "^1.4.3",
+		"@types/leaflet-fullscreen": "^1.0.4",
+		"leaflet-heatmap": "^1.0.0",
+		"nightdocs": "^1.0.1",
+		"postcss-copy": "^7.1.0",
+		"postcss-import": "^12.0.1",
+		"rollup": "^1.6.0",
+		"rollup-plugin-commonjs": "^9.2.1",
+		"rollup-plugin-node-resolve": "^4.0.1",
+		"rollup-plugin-postcss": "^2.0.3",
+		"rollup-plugin-replace": "^2.1.0",
+		"rollup-plugin-terser": "^4.0.4"
+	},
+	"docpress": {
+		"github": "ConnectedHumber/Air-Quality-Web",
+		"markdown": {
+			"xhtmlOut": true
+		},
+		"css": [
+			"docs/theme.css"
+		]
+	}
 }
