diff --git a/bam/forms.py b/bam/forms.py
index 0abd6c06c7cea81e5d4291df2312996abd04af25..c2b40c5baa459ed16c210ec034df5b3c415c434c 100644
--- a/bam/forms.py
+++ b/bam/forms.py
@@ -1,14 +1,21 @@
 from flask_wtf import FlaskForm
-from wtforms import StringField, PasswordField, SubmitField, BooleanField
+from wtforms import StringField, PasswordField, SubmitField, BooleanField, DecimalField
 from wtforms.fields.html5 import EmailField
-from wtforms.validators import DataRequired, Length, Email, EqualTo, ValidationError
+from wtforms.validators import (
+    DataRequired,
+    Length,
+    Email,
+    EqualTo,
+    ValidationError,
+    Regexp,
+)
 from bam.models import User
 
 
 class RegistrationForm(FlaskForm):
     username = StringField(
         "Username",
-        validators=[DataRequired()],
+        validators=[DataRequired(), Length(max=16)],
         render_kw={"placeholder": "Enter a username"},
     )
     email = EmailField(
@@ -23,7 +30,10 @@ class RegistrationForm(FlaskForm):
     )
     confirm_password = PasswordField(
         "Confirm Password",
-        validators=[DataRequired(), EqualTo("password")],
+        validators=[
+            DataRequired(),
+            EqualTo("password", message="Passwords do not match."),
+        ],
         render_kw={"placeholder": "Re-enter your password"},
     )
 
@@ -51,3 +61,19 @@ class LoginForm(FlaskForm):
     )
     remember = BooleanField("Remember Me")
     submit = SubmitField("Login")
+
+
+class AddBookForm(FlaskForm):
+    title = StringField("Title", validators=[DataRequired()])
+    author = StringField("Author", validators=[DataRequired()])
+    isbn = StringField(
+        "ISBN",
+        validators=[
+            Regexp(
+                r"^(\d{10}\d{3}?)?$", message="Invalid ISBN. Must be 10 or 13 digits."
+            ),
+        ],
+    )
+
+    price = DecimalField("Price", default=0.0)
+    submit = SubmitField("Add book")
diff --git a/bam/models.py b/bam/models.py
index 57bff8f31617dbeea747e151b7f8da8457886f4d..76faa81ad78d8cb5184f2824023a10b11ae427f3 100644
--- a/bam/models.py
+++ b/bam/models.py
@@ -10,9 +10,20 @@ def load_user(user_id):
 class User(db.Model, UserMixin):
     id = db.Column(db.Integer, primary_key=True)
     email = db.Column(db.String(120), unique=True, nullable=False)
-    username = db.Column(db.String(60), unique=True, nullable=False)
+    username = db.Column(db.String(16), unique=True, nullable=False)
     password = db.Column(db.String(60), nullable=False)
     role = db.Column(db.String(10), default="user")
 
     def __repr__(self):
         return f"User({self.email}, {self.password})"
+
+
+class Book(db.Model):
+    id = db.Column(db.Integer, primary_key=True)
+    title = db.Column(db.String(120), nullable=False)
+    author = db.Column(db.String(120), nullable=False)
+    isbn = db.Column(db.String(13))
+    price = db.Column(db.Float, default=0.0)
+    addedby = db.Column(db.Integer, db.ForeignKey("user.id"), nullable=False)
+
+    users = db.relationship(User)
\ No newline at end of file
diff --git a/bam/routes.py b/bam/routes.py
index 426be328d243db96ed6490d67586abcc4e6851c5..c6fbb023b16cfcaa0a5dc4c6d9eae91e208ccabc 100644
--- a/bam/routes.py
+++ b/bam/routes.py
@@ -1,15 +1,15 @@
 from flask import render_template, url_for, flash, redirect
-from flask_login import login_user, current_user, logout_user
+from flask_login import login_user, current_user, logout_user, login_required
 from bam import app, db, bcrypt
-from bam.forms import RegistrationForm, LoginForm
-from bam.models import User
+from bam.forms import RegistrationForm, LoginForm, AddBookForm
+from bam.models import User, Book
 
 
 @app.route("/")
 @app.route("/home")
 def home():
     if current_user.is_authenticated:
-        return render_template("dash.html")
+        return render_template("books.html")
     return render_template("home.html")
 
 
@@ -50,4 +50,22 @@ def login():
 def logout():
     logout_user()
     # flash("You have been successfully logged out", "success")
-    return redirect(url_for("home"))
\ No newline at end of file
+    return redirect(url_for("home"))
+
+
+@app.route("/add", methods=["GET", "POST"])
+@login_required
+def addBook():
+    form = AddBookForm()
+    if form.validate_on_submit():
+        book = Book(
+            title=form.title.data,
+            author=form.author.data,
+            isbn=form.isbn.data,
+            price=form.price.data,
+            addedby=current_user.id,
+        )
+        db.session.add(book)
+        db.session.commit()
+        return redirect(url_for("home"))
+    return render_template("add.html", title="Add book", form=form)
\ No newline at end of file
diff --git a/bam/static/bookform.css b/bam/static/bookform.css
new file mode 100644
index 0000000000000000000000000000000000000000..4b190c7fa13ffe0e83c3a8856518fc3179ca93fc
--- /dev/null
+++ b/bam/static/bookform.css
@@ -0,0 +1,70 @@
+.content {
+  align-self: flex-start;
+}
+
+form {
+  width: 100%;
+}
+
+form {
+  display: flex;
+  flex-direction: column;
+  min-width: min(90vw, 400px);
+}
+
+form > label {
+  padding-bottom: 5px;
+}
+
+input {
+  font-family: Roboto;
+  font-size: 16px;
+  border-radius: 3px;
+  padding: 12px;
+  background-color: rgba(10, 10, 10, 0.5);
+  border: 1px solid #111;
+  color: #eee;
+  transition: background 0.3s;
+}
+input:hover {
+  --hcolor: rgba(10, 10, 10, 0.7);
+  background-color: var(--hcolor);
+  border: 1px solid var(--hcolor);
+}
+input:focus,
+input:active {
+  background-color: rgba(30, 30, 30, 0.5);
+  border: 1px solid grey;
+  outline: none;
+}
+
+label {
+  text-transform: uppercase;
+  font-weight: 700;
+  font-size: 0.9rem;
+  letter-spacing: 1px;
+}
+
+.field-error {
+  font-style: oblique;
+  color: var(--red);
+  font-size: 0.9rem;
+}
+
+[type="submit"] {
+  background-color: var(--red);
+  border: none;
+  font-weight: 700;
+  text-transform: uppercase;
+  letter-spacing: 1px;
+}
+
+[type="submit"]:hover {
+  background-color: var(--dark-red);
+  cursor: pointer;
+}
+
+label,
+[type="submit"] {
+  margin-top: 10px;
+}
diff --git a/bam/static/dash.css b/bam/static/dash.css
new file mode 100644
index 0000000000000000000000000000000000000000..11d35835e99fdf85b58a82e50588bc59bec7ab43
--- /dev/null
+++ b/bam/static/dash.css
@@ -0,0 +1,104 @@
+@import url("https://fonts.googleapis.com/css2?family=Roboto:wght@100;300;400;500;700;900&display=swap");
+html,
+body {
+  margin: 0;
+  padding: 0;
+  min-height: 100vh;
+}
+
+:root {
+  --red: #e50914;
+  --dark-red: #bb0009;
+  --t-dark: rgba(0, 0, 0, 0.8);
+  --t-darker: rgba(0, 0, 0, 0.9);
+  --nav-padding-top: 20px;
+  --nav-padding-side: 50px;
+  --logo-height: 60px;
+  --nav-gap: 20px;
+}
+
+@media screen and (max-width: 600px) {
+  :root {
+    --nav-padding-top: 15px;
+    --nav-padding-side: 15px;
+    --logo-height: 50px;
+  }
+  .navbar {
+    flex-wrap: wrap;
+  }
+
+  .navbar .space {
+    display: none;
+  }
+}
+
+* {
+  box-sizing: border-box;
+}
+
+body {
+  background-color: #222;
+  color: white;
+  font-family: Roboto;
+}
+
+.maincontainer {
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  min-height: 100vh;
+}
+
+.navbar {
+  background: linear-gradient(to bottom, #040404, transparent);
+  align-items: center;
+  padding: var(--nav-padding-top) var(--nav-padding-side);
+  display: flex;
+  width: 100%;
+  gap: var(--nav-gap);
+}
+
+.navbar .logo {
+  height: var(--logo-height);
+  margin-right: calc(var(--nav-padding-side) - var(--nav-gap));
+}
+
+.navbar .logo img {
+  height: 100%;
+  filter: drop-shadow(2px 2px 6px #111);
+}
+
+.navbar a {
+  text-decoration: none;
+  font-size: 20px;
+  font-weight: 500;
+  color: #aaa;
+  transition: color 0.2s ease;
+}
+
+.navbar a.active {
+  color: #eee;
+}
+
+.navbar a:hover {
+  color: #fff;
+}
+
+.navbar .space,
+.content {
+  flex-grow: 1;
+}
+
+.content {
+  padding: 0 var(--nav-padding-side);
+}
+
+.credits {
+  padding: 15px;
+  font-size: 0.7rem;
+  color: #888;
+  opacity: 0.5;
+  background: linear-gradient(to bottom, transparent, #111);
+  width: 100%;
+  text-align: center;
+}
diff --git a/bam/templates/add.html b/bam/templates/add.html
new file mode 100644
index 0000000000000000000000000000000000000000..83ab79c1c14cb130b21604ca9b511fadb63ccf46
--- /dev/null
+++ b/bam/templates/add.html
@@ -0,0 +1,24 @@
+{% extends "dash.html" %} {% set active_page = "add" %} {% block head %}
+<link
+  rel="stylesheet"
+  href="{{ url_for('static', filename='bookform.css') }}"
+/>
+{% endblock %} {% block content %}
+<form class="addBookForm" action="" method="POST">
+  {{ form.hidden_tag() }}
+  <h1>Add a Book</h1>
+  {{ form.title.label() }} {{ form.title }} {% for error in form.title.errors %}
+  <div class="field-error">{{ error }}</div>
+  {% endfor %} {{ form.author.label() }} {{ form.author }} {% for error in
+  form.author.errors %}
+  <div class="field-error">{{ error }}</div>
+  {% endfor %} {{ form.isbn.label() }} {{ form.isbn }} {% for error in
+  form.isbn.errors %}
+  <div class="field-error">{{ error }}</div>
+  {% endfor %} {{ form.price.label() }} {{ form.price }} {% for error in
+  form.price.errors %}
+  <div class="field-error">{{ error }}</div>
+  {% endfor %} {{ form.submit() }}
+</form>
+
+{% endblock %}
diff --git a/bam/templates/books.html b/bam/templates/books.html
new file mode 100644
index 0000000000000000000000000000000000000000..b860055b746a66031738846d85113afc0213b35b
--- /dev/null
+++ b/bam/templates/books.html
@@ -0,0 +1,3 @@
+{% extends "dash.html" %} {% set active_page = "books" %} {% block content %}
+<div>WIP</div>
+{% endblock %}
diff --git a/bam/templates/dash.html b/bam/templates/dash.html
index 439b8cc766edea2ed31d06659c115492fb0758c3..f5e6510c6a25362128711a76dce1b5863d902e8a 100644
--- a/bam/templates/dash.html
+++ b/bam/templates/dash.html
@@ -3,9 +3,41 @@
   <head>
     <meta charset="UTF-8" />
     <meta name="viewport" content="width=device-width, initial-scale=1.0" />
-    <title>BAM - Dashboard</title>
+    {% if title %}
+    <title>BAM - {{ title }}</title>
+    {% else %}
+    <title>BAM</title>
+    {% endif %}
+    <link
+      rel="stylesheet"
+      href="{{ url_for('static', filename='dash.css') }}"
+    />
+    {% block head %}{% endblock %}
   </head>
   <body>
-    Yaaay - you are authorized!
+    <div class="maincontainer">
+      <div class="navbar">
+        <div class="logo">
+          <a href="{{ url_for('home') }}">
+            <img src="https://i.imgur.com/t2ZlJ06.png" />
+          </a>
+        </div>
+        <a
+          href="{{ url_for('home') }}"
+          class="{{ 'active' if active_page == 'books' else '' }}"
+          >Home</a
+        >
+        <a
+          href="{{ url_for('addBook') }}"
+          class="{{ 'active' if active_page == 'add' else '' }}"
+          >Add a book</a
+        >
+        <div class="space"></div>
+        <a href="#">Settings</a>
+        <a href="{{ url_for('logout') }}">Logout</a>
+      </div>
+      <div class="content">{% block content %}{% endblock %}</div>
+      <div class="credits">Built with ❤ using Flask</div>
+    </div>
   </body>
 </html>
diff --git a/create_db.py b/create_db.py
index e6f7d5eb03e48a182b6b0eb43cf7731af9d02ba8..3f5bffef1bbe594b5b8bdcd6b5d6fcd268a8eb24 100644
--- a/create_db.py
+++ b/create_db.py
@@ -1,3 +1,15 @@
-from bam import db
+from bam import db, bcrypt
+from bam.models import User
 
+# Create databases
 db.create_all()
+
+# Create a test user
+db.session.add(
+    User(
+        username="bookmaster",
+        email="bookmaster@example.com",
+        password=bcrypt.generate_password_hash("masterofbooks").decode("utf-8"),
+    )
+)
+db.session.commit()
\ No newline at end of file