diff --git a/.gitignore b/.gitignore
index 68bc17f9ff2104a9d7b6777058bb4c343ca72609..bc8bd2d0b0160900752b8badde008f52844f2f50 100644
--- a/.gitignore
+++ b/.gitignore
@@ -158,3 +158,5 @@ cython_debug/
 #  and can be added to the global gitignore or merged into this file.  For a more nuclear
 #  option (not recommended) you can uncomment the following to ignore the entire idea folder.
 #.idea/
+
+config.py
\ No newline at end of file
diff --git a/README.md b/README.md
index c4464a1da22e4a6ae10759d2d2547c86b7e30f3e..c8183620c6c99cee75dad64b9803f8f7368d4e4b 100644
--- a/README.md
+++ b/README.md
@@ -1,2 +1,11 @@
 # PizzaPalace
 GCSE Computer Science Challenge
+
+## Installation
+```
+git clone https://github.com/TheJoeCoder/PizzaPalace
+cd PizzaPalace
+pip install -r requirements.txt
+echo "SECRET_KEY = 'SOME_KEY'" > app/config.py
+flask --app=pizza dev
+```
\ No newline at end of file
diff --git a/pizza/__init__.py b/pizza/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..3418777df1409729804f9130a1efbfcfa0382653
--- /dev/null
+++ b/pizza/__init__.py
@@ -0,0 +1,27 @@
+from flask import Flask
+from flask_appconfig import AppConfig
+from flask_bootstrap import Bootstrap
+
+from .frontend import frontend
+from .nav import nav
+
+
+def create_app(configfile=None):
+    app = Flask(__name__)
+
+    # Flask-Appconfig
+    AppConfig(app)
+
+    # Install Bootstrap
+    Bootstrap(app)
+
+    # Register blueprints
+    app.register_blueprint(frontend)
+
+    # Disable CDN Support
+    app.config['BOOTSTRAP_SERVE_LOCAL'] = True
+
+    # Init navigation
+    nav.init_app(app)
+
+    return app
\ No newline at end of file
diff --git a/pizza/forms.py b/pizza/forms.py
new file mode 100644
index 0000000000000000000000000000000000000000..46e62392f77ea6369ba7934a24da74edaca8df42
--- /dev/null
+++ b/pizza/forms.py
@@ -0,0 +1,22 @@
+from flask_wtf import Form
+from wtforms.fields import *
+from wtforms.validators import Required, Email
+
+
+class SignupForm(Form):
+    name = TextField(u'Your name', validators=[Required()])
+    password = TextField(u'Your favorite password', validators=[Required()])
+    email = TextField(u'Your email address', validators=[Email()])
+    birthday = DateField(u'Your birthday')
+
+    a_float = FloatField(u'A floating point number')
+    a_decimal = DecimalField(u'Another floating point number')
+    a_integer = IntegerField(u'An integer')
+
+    now = DateTimeField(u'Current time',
+                        description='...for no particular reason')
+    sample_file = FileField(u'Your favorite file')
+    eula = BooleanField(u'I did not read the terms and conditions',
+                        validators=[Required('You must agree to not agree!')])
+
+    submit = SubmitField(u'Signup')
\ No newline at end of file
diff --git a/pizza/frontend.py b/pizza/frontend.py
new file mode 100644
index 0000000000000000000000000000000000000000..3452c943909052aed09134dc25ba47b3e445d51f
--- /dev/null
+++ b/pizza/frontend.py
@@ -0,0 +1,47 @@
+from flask import Blueprint, render_template, flash, redirect, url_for
+from flask_bootstrap import __version__ as FLASK_BOOTSTRAP_VERSION
+from flask_nav.elements import Navbar, View, Subgroup, Link, Text, Separator
+from markupsafe import escape
+
+from .forms import SignupForm
+from .nav import nav
+
+frontend = Blueprint('frontend', __name__)
+
+# We're adding a navbar as well through flask-navbar. In our example, the
+# navbar has an usual amount of Link-Elements, more commonly you will have a
+# lot more View instances.
+nav.register_element('frontend_top', Navbar(
+    View('Flask-Bootstrap', '.index'),
+    View('Home', '.index'),
+    View('Forms Example', '.example_form'),
+    View('Debug-Info', 'debug.debug_root'),
+    Subgroup(
+        'Docs',
+        Link('Flask-Bootstrap', 'http://pythonhosted.org/Flask-Bootstrap'),
+        Link('Flask-AppConfig', 'https://github.com/mbr/flask-appconfig'),
+        Link('Flask-Debug', 'https://github.com/mbr/flask-debug'),
+        Separator(),
+        Text('Bootstrap'),
+        Link('Getting started', 'http://getbootstrap.com/getting-started/'),
+        Link('CSS', 'http://getbootstrap.com/css/'),
+        Link('Components', 'http://getbootstrap.com/components/'),
+        Link('Javascript', 'http://getbootstrap.com/javascript/'),
+        Link('Customize', 'http://getbootstrap.com/customize/'), ),
+    Text('Using Flask-Bootstrap {}'.format(FLASK_BOOTSTRAP_VERSION)), ))
+
+
+@frontend.route('/')
+def index():
+    return render_template('index.html')
+
+
+@frontend.route('/example-form/', methods=('GET', 'POST'))
+def example_form():
+    form = SignupForm()
+    if form.validate_on_submit():
+        flash('Hello, {}. You have successfully signed up'
+              .format(escape(form.name.data)))
+        return redirect(url_for('.index'))
+
+    return render_template('signup.html', form=form)
\ No newline at end of file
diff --git a/pizza/nav.py b/pizza/nav.py
new file mode 100644
index 0000000000000000000000000000000000000000..14e4ee77fb565bb7560711dcda065267f1a38418
--- /dev/null
+++ b/pizza/nav.py
@@ -0,0 +1,3 @@
+from flask_nav import Nav
+
+nav = Nav()
\ No newline at end of file
diff --git a/pizza/static/html5shiv.min.js b/pizza/static/html5shiv.min.js
new file mode 100644
index 0000000000000000000000000000000000000000..92f741f4b961bf52a0e3305f036dbffcf0293785
--- /dev/null
+++ b/pizza/static/html5shiv.min.js
@@ -0,0 +1,4 @@
+/**
+* @preserve HTML5 Shiv 3.7.3-pre | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed
+*/
+!function(a,b){function c(a,b){var c=a.createElement("p"),d=a.getElementsByTagName("head")[0]||a.documentElement;return c.innerHTML="x<style>"+b+"</style>",d.insertBefore(c.lastChild,d.firstChild)}function d(){var a=t.elements;return"string"==typeof a?a.split(" "):a}function e(a,b){var c=t.elements;"string"!=typeof c&&(c=c.join(" ")),"string"!=typeof a&&(a=a.join(" ")),t.elements=c+" "+a,j(b)}function f(a){var b=s[a[q]];return b||(b={},r++,a[q]=r,s[r]=b),b}function g(a,c,d){if(c||(c=b),l)return c.createElement(a);d||(d=f(c));var e;return e=d.cache[a]?d.cache[a].cloneNode():p.test(a)?(d.cache[a]=d.createElem(a)).cloneNode():d.createElem(a),!e.canHaveChildren||o.test(a)||e.tagUrn?e:d.frag.appendChild(e)}function h(a,c){if(a||(a=b),l)return a.createDocumentFragment();c=c||f(a);for(var e=c.frag.cloneNode(),g=0,h=d(),i=h.length;i>g;g++)e.createElement(h[g]);return e}function i(a,b){b.cache||(b.cache={},b.createElem=a.createElement,b.createFrag=a.createDocumentFragment,b.frag=b.createFrag()),a.createElement=function(c){return t.shivMethods?g(c,a,b):b.createElem(c)},a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+d().join().replace(/[\w\-:]+/g,function(a){return b.createElem(a),b.frag.createElement(a),'c("'+a+'")'})+");return n}")(t,b.frag)}function j(a){a||(a=b);var d=f(a);return!t.shivCSS||k||d.hasCSS||(d.hasCSS=!!c(a,"article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}")),l||i(a,d),a}var k,l,m="3.7.3-pre",n=a.html5||{},o=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,p=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,q="_html5shiv",r=0,s={};!function(){try{var a=b.createElement("a");a.innerHTML="<xyz></xyz>",k="hidden"in a,l=1==a.childNodes.length||function(){b.createElement("a");var a=b.createDocumentFragment();return"undefined"==typeof a.cloneNode||"undefined"==typeof a.createDocumentFragment||"undefined"==typeof a.createElement}()}catch(c){k=!0,l=!0}}();var t={elements:n.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output picture progress section summary template time video",version:m,shivCSS:n.shivCSS!==!1,supportsUnknownElements:l,shivMethods:n.shivMethods!==!1,type:"default",shivDocument:j,createElement:g,createDocumentFragment:h,addElements:e};a.html5=t,j(b),"object"==typeof module&&module.exports&&(module.exports=t)}("undefined"!=typeof window?window:this,document);
\ No newline at end of file
diff --git a/pizza/static/pizza-palace.css b/pizza/static/pizza-palace.css
new file mode 100644
index 0000000000000000000000000000000000000000..91a0744626dbd329a744924555f94e3322da8fbc
--- /dev/null
+++ b/pizza/static/pizza-palace.css
@@ -0,0 +1,3 @@
+.jumbotron {
+    margin-top: 1em;  /* add a little space */
+  }
\ No newline at end of file
diff --git a/pizza/static/respond.min.js b/pizza/static/respond.min.js
new file mode 100644
index 0000000000000000000000000000000000000000..51bf6b221795b5f42a9276a955dc92bebfb38fa4
--- /dev/null
+++ b/pizza/static/respond.min.js
@@ -0,0 +1,6 @@
+/*! Respond.js v1.4.2: min/max-width media query polyfill
+ * Copyright 2014 Scott Jehl
+ * Licensed under MIT
+ * http://j.mp/respondjs */
+
+ !function(a){"use strict";a.matchMedia=a.matchMedia||function(a){var b,c=a.documentElement,d=c.firstElementChild||c.firstChild,e=a.createElement("body"),f=a.createElement("div");return f.id="mq-test-1",f.style.cssText="position:absolute;top:-100em",e.style.background="none",e.appendChild(f),function(a){return f.innerHTML='&shy;<style media="'+a+'"> #mq-test-1 { width: 42px; }</style>',c.insertBefore(e,d),b=42===f.offsetWidth,c.removeChild(e),{matches:b,media:a}}}(a.document)}(this),function(a){"use strict";function b(){v(!0)}var c={};a.respond=c,c.update=function(){};var d=[],e=function(){var b=!1;try{b=new a.XMLHttpRequest}catch(c){b=new a.ActiveXObject("Microsoft.XMLHTTP")}return function(){return b}}(),f=function(a,b){var c=e();c&&(c.open("GET",a,!0),c.onreadystatechange=function(){4!==c.readyState||200!==c.status&&304!==c.status||b(c.responseText)},4!==c.readyState&&c.send(null))},g=function(a){return a.replace(c.regex.minmaxwh,"").match(c.regex.other)};if(c.ajax=f,c.queue=d,c.unsupportedmq=g,c.regex={media:/@media[^\{]+\{([^\{\}]*\{[^\}\{]*\})+/gi,keyframes:/@(?:\-(?:o|moz|webkit)\-)?keyframes[^\{]+\{(?:[^\{\}]*\{[^\}\{]*\})+[^\}]*\}/gi,comments:/\/\*[^*]*\*+([^/][^*]*\*+)*\//gi,urls:/(url\()['"]?([^\/\)'"][^:\)'"]+)['"]?(\))/g,findStyles:/@media *([^\{]+)\{([\S\s]+?)$/,only:/(only\s+)?([a-zA-Z]+)\s?/,minw:/\(\s*min\-width\s*:\s*(\s*[0-9\.]+)(px|em)\s*\)/,maxw:/\(\s*max\-width\s*:\s*(\s*[0-9\.]+)(px|em)\s*\)/,minmaxwh:/\(\s*m(in|ax)\-(height|width)\s*:\s*(\s*[0-9\.]+)(px|em)\s*\)/gi,other:/\([^\)]*\)/g},c.mediaQueriesSupported=a.matchMedia&&null!==a.matchMedia("only all")&&a.matchMedia("only all").matches,!c.mediaQueriesSupported){var h,i,j,k=a.document,l=k.documentElement,m=[],n=[],o=[],p={},q=30,r=k.getElementsByTagName("head")[0]||l,s=k.getElementsByTagName("base")[0],t=r.getElementsByTagName("link"),u=function(){var a,b=k.createElement("div"),c=k.body,d=l.style.fontSize,e=c&&c.style.fontSize,f=!1;return b.style.cssText="position:absolute;font-size:1em;width:1em",c||(c=f=k.createElement("body"),c.style.background="none"),l.style.fontSize="100%",c.style.fontSize="100%",c.appendChild(b),f&&l.insertBefore(c,l.firstChild),a=b.offsetWidth,f?l.removeChild(c):c.removeChild(b),l.style.fontSize=d,e&&(c.style.fontSize=e),a=j=parseFloat(a)},v=function(b){var c="clientWidth",d=l[c],e="CSS1Compat"===k.compatMode&&d||k.body[c]||d,f={},g=t[t.length-1],p=(new Date).getTime();if(b&&h&&q>p-h)return a.clearTimeout(i),i=a.setTimeout(v,q),void 0;h=p;for(var s in m)if(m.hasOwnProperty(s)){var w=m[s],x=w.minw,y=w.maxw,z=null===x,A=null===y,B="em";x&&(x=parseFloat(x)*(x.indexOf(B)>-1?j||u():1)),y&&(y=parseFloat(y)*(y.indexOf(B)>-1?j||u():1)),w.hasquery&&(z&&A||!(z||e>=x)||!(A||y>=e))||(f[w.media]||(f[w.media]=[]),f[w.media].push(n[w.rules]))}for(var C in o)o.hasOwnProperty(C)&&o[C]&&o[C].parentNode===r&&r.removeChild(o[C]);o.length=0;for(var D in f)if(f.hasOwnProperty(D)){var E=k.createElement("style"),F=f[D].join("\n");E.type="text/css",E.media=D,r.insertBefore(E,g.nextSibling),E.styleSheet?E.styleSheet.cssText=F:E.appendChild(k.createTextNode(F)),o.push(E)}},w=function(a,b,d){var e=a.replace(c.regex.comments,"").replace(c.regex.keyframes,"").match(c.regex.media),f=e&&e.length||0;b=b.substring(0,b.lastIndexOf("/"));var h=function(a){return a.replace(c.regex.urls,"$1"+b+"$2$3")},i=!f&&d;b.length&&(b+="/"),i&&(f=1);for(var j=0;f>j;j++){var k,l,o,p;i?(k=d,n.push(h(a))):(k=e[j].match(c.regex.findStyles)&&RegExp.$1,n.push(RegExp.$2&&h(RegExp.$2))),o=k.split(","),p=o.length;for(var q=0;p>q;q++)l=o[q],g(l)||m.push({media:l.split("(")[0].match(c.regex.only)&&RegExp.$2||"all",rules:n.length-1,hasquery:l.indexOf("(")>-1,minw:l.match(c.regex.minw)&&parseFloat(RegExp.$1)+(RegExp.$2||""),maxw:l.match(c.regex.maxw)&&parseFloat(RegExp.$1)+(RegExp.$2||"")})}v()},x=function(){if(d.length){var b=d.shift();f(b.href,function(c){w(c,b.href,b.media),p[b.href]=!0,a.setTimeout(function(){x()},0)})}},y=function(){for(var b=0;b<t.length;b++){var c=t[b],e=c.href,f=c.media,g=c.rel&&"stylesheet"===c.rel.toLowerCase();e&&g&&!p[e]&&(c.styleSheet&&c.styleSheet.rawCssText?(w(c.styleSheet.rawCssText,e,f),p[e]=!0):(!/^([a-zA-Z:]*\/\/)/.test(e)&&!s||e.replace(RegExp.$1,"").split("/")[0]===a.location.host)&&("//"===e.substring(0,2)&&(e=a.location.protocol+e),d.push({href:e,media:f})))}x()};y(),c.update=y,c.getEmValue=u,a.addEventListener?a.addEventListener("resize",b,!1):a.attachEvent&&a.attachEvent("onresize",b)}}(this);
\ No newline at end of file
diff --git a/pizza/templates/base.html b/pizza/templates/base.html
new file mode 100644
index 0000000000000000000000000000000000000000..b10b080aa160b9e48a36f7bd7802545ca144d223
--- /dev/null
+++ b/pizza/templates/base.html
@@ -0,0 +1,23 @@
+{%- extends "bootstrap/base.html" %}
+ 
+ {# Set default title #}
+ {% block title %}Pizza Palace{% endblock %}
+ 
+ {# Fix legacy background #}
+ {% import "bootstrap/fixes.html" as fixes %}
+ {% block head %}
+ {{super()}}
+ {{fixes.ie8()}}
+ {%- endblock %}
+ 
+ {# Add CSS Files #}
+ {% block styles -%}
+     {{super()}}
+     <link rel="stylesheet" type="text/css"
+           href="{{url_for('static', filename='pizza-palace.css')}}">
+ {% endblock %}
+ 
+ {# Navbar #}
+ {% block navbar %}
+ {{nav.frontend_top.render()}}
+ {% endblock %}
\ No newline at end of file
diff --git a/pizza/templates/index.html b/pizza/templates/index.html
new file mode 100644
index 0000000000000000000000000000000000000000..250e59ad5dbd759f6847150561d321845de91b2b
--- /dev/null
+++ b/pizza/templates/index.html
@@ -0,0 +1,30 @@
+{%- extends "base.html" %}
+ 
+ {# Bootstrap macros #}
+ {% import "bootstrap/utils.html" as utils %}
+ 
+ 
+ {# Content #}
+ {% block content %}
+   <div class="container">
+   {%- with messages = get_flashed_messages(with_categories=True) %}
+   {%- if messages %}
+     <div class="row">
+       <div class="col-md-12">
+         {{utils.flashed_messages(messages)}}
+       </div>
+     </div>
+   {%- endif %}
+   {%- endwith %}
+     <div class="jumbotron">
+       <h1>Welcome to Flask-Bootstrap</h1>
+       <p>This example application demonstrates some (but not all!) of the
+       features of <a href="http://pythonhosted.org/Flask-Bootstrap">
+       Flask-Bootstrap</a>.</p>
+       <p>
+         <a class="btn btn-lg btn-default" role="button"
+            href="http://pythonhosted.org/Flask-Bootstrap" >Show docs</a>
+       </p>
+     </div>
+    </div>
+ {%- endblock %}
\ No newline at end of file
diff --git a/pizza/templates/signup.html b/pizza/templates/signup.html
new file mode 100644
index 0000000000000000000000000000000000000000..3e771e519f1df2bb648604952d52b38e49f8e271
--- /dev/null
+++ b/pizza/templates/signup.html
@@ -0,0 +1,19 @@
+{% import "bootstrap/wtf.html" as wtf %}
+
+{%- extends "base.html" %}
+
+
+{% block content %}
+   <div class="container">
+      <div class="jumbotron">
+        <h1>Signup for our awesome service</h1>
+        <p>Note: Your data isn't going anywhere.</p>
+      </div>
+   <div class="col-md-12">
+     {% if request.args.get('legacy') -%}
+       {{wtf.quick_form(form, novalidate=True)}}
+     {%- else -%}
+       {{form|render_form()}}
+     {%- endif %}
+   </div>
+{%- endblock %}
\ No newline at end of file
diff --git a/requirements.txt b/requirements.txt
new file mode 100644
index 0000000000000000000000000000000000000000..120dc8d84bdcfef9afb8135f8e84ca3c6b41b832
--- /dev/null
+++ b/requirements.txt
@@ -0,0 +1,6 @@
+flask-appconfig>=0.10
+flask-bootstrap
+flask-nav
+flask-debug
+flask-wtf
+flask==2.3.2
\ No newline at end of file