diff --git a/.gitignore b/.gitignore
index 42680c5..9599041 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,10 @@
/target
/html/opentally.js
/html/opentally_*.wasm
+
+# Jekyll
+/homepage/_site
+/homepage/.sass-cache
+/homepage/.jekyll-cache
+/homepage/.jekyll-metadata
+/homepage/vendor
diff --git a/README.md b/README.md
index 0d72cb7..09d7ee2 100644
--- a/README.md
+++ b/README.md
@@ -30,7 +30,7 @@ OpenTally is highly customisable, including options for:
After preparing the [BLT file](https://yingtongli.me/git/OpenTally/about/docs/blt.md), open the web UI. Select the BLT file, and click *Count*. OpenTally will count the election and display the results in a count sheet.
-By clicking *Show advanced options*, you can customise the options used for the count. A detailed explanation of the various options can be found [here](https://yingtongli.me/git/OpenTally/about/docs/options.md).
+By clicking *Show advanced options*, you can customise the options used for the count. A detailed explanation of the various options can be found [here](/opentally/docs/options.html).
Once the count is complete, you can click *Print result* to generate a printable result report.
diff --git a/docs/options.md b/docs/options.md
index 59d7b87..e974f9b 100644
--- a/docs/options.md
+++ b/docs/options.md
@@ -27,7 +27,7 @@ The preset dropdown allows you to choose from a hardcoded list of preloaded STV
Exceptions:
-* [E1] When generating random numbers, OpenTally uses a [deterministic random number generator based on SHA-256](rng.md), rather than the Wichmann–Hill(-based) algorithm.
+* [E1] When generating random numbers, OpenTally uses a [deterministic random number generator based on SHA-256](https://yingtongli.me/git/OpenTally/about/docs/rng.md), rather than the Wichmann–Hill(-based) algorithm.
* [E2] When breaking ties backwards, OpenTally selects the candidate who had more/fewer votes at the last stage when *any* tied candidate had more/fewer votes, rather than the method described in the legislation (when each all had unequal votes). The OpenTally developers regard the method described in the legislation as a defect. For an independent discussion, see Conway et al.
* [E3] A tie between 2 candidates for the final vacancy will be broken backwards then at random, rather than the method described in the legislation.
* [E4] Bulk exclusion is not performed, as the prescribed rules are more conservative than OpenTally's. See also the section on *Bulk exclusion* for further discussion.
@@ -36,7 +36,7 @@ Exceptions:
* [E7] No distinction is made between stages and substages (during exclusion). This affects only the numbering of stages and not the result.
* [E8] By default, the quota is always calculated to 2 decimal places. For full ERS76 (ERS73) compliance, set *Round quota to 0 d.p.* when the quota is more than 100 (100 or more).
-For details of validation, see [validation.md](validation.md).
+For details of validation, see [validation.md](https://yingtongli.me/git/OpenTally/about/docs/validation.md).
This functionality is not available on the command line.
@@ -158,11 +158,11 @@ This option allows you to input an arbitrary value to seed the deterministic ran
The default value is the current date, formatted YYYYMMDD.
-The algorithm used by the random number generator is specified at [rng.md](rng.md).
+The algorithm used by the random number generator is specified at [rng.md](https://yingtongli.me/git/OpenTally/about/docs/rng.md).
## Constraints (--constraints)
-This file selector allows you to load a [CON file](con.md) specifying constraints on the election. For example, if a certain minimum or maximum number of candidates can be elected from a particular category.
+This file selector allows you to load a [CON file](https://yingtongli.me/git/OpenTally/about/docs/con.md) specifying constraints on the election. For example, if a certain minimum or maximum number of candidates can be elected from a particular category.
OpenTally applies constraints using the Grey–Fitzgerald method. Whenever a candidate is declared elected or excluded, any candidate who must be elected to secure a conformant result is deemed *guarded*, and any candidate who must not be elected to secure a conformant result is deemed *doomed*. Any candidate who is doomed is excluded at the next opportunity. Any candidate who is guarded is prevented from being excluded.
diff --git a/homepage/404.html b/homepage/404.html
new file mode 100644
index 0000000..086a5c9
--- /dev/null
+++ b/homepage/404.html
@@ -0,0 +1,25 @@
+---
+permalink: /404.html
+layout: default
+---
+
+
+
+
No downloads or sign-ups are required. OpenTally counts are computed entirely inside your browser, and no data ever leaves your computer.
+
+
+
Wide range of STV systems
+
OpenTally supports Gregory (inclusive and exclusive, weighted and unweighted), Meek and Wright variants of the single transferable vote.
+
+
+
Support for arbitrary constraints
+
OpenTally is the only publicly available election counting software to support arbitrary combinations of constraints, such as gender quotas and other affirmative action requirements.
+
+
+
Free and open source
+
Source code for OpenTally is publicly available under the GNU AGPLv3.
Single transferable vote rules designed for hand-counting often contain references to ‘parcels’ (or ‘bundles’ or ‘batches’), ‘further parcels’ and sometimes even ‘subparcels’.
WebAssembly is a technology for executing compiled programs in the web browser at near-native speeds. However, it has a number of current limitations, including that it does not support coroutines/asynchronicity.
+
In OpenTally, WebAssembly is used to run code for counting an election. This…