diff --git a/account.php b/account.php
new file mode 100644
index 0000000000000000000000000000000000000000..4812057ebbca5dcb4b604e478dae5fa9506db761
--- /dev/null
+++ b/account.php
@@ -0,0 +1,132 @@
+<?php 
+
+if (!isset($_SESSION['auth'])) {
+    header('Location: /signin?callback=/account');
+    exit;
+}
+
+function get_gravatar_url( $email ) {
+    // Trim leading and trailing whitespace from
+    // an email address and force all characters
+    // to lower case
+    $address = strtolower( trim( $email ) );
+  
+    // Create an SHA256 hash of the final string
+    $hash = hash( 'sha256', $address );
+  
+    // Grab the actual image URL
+    return 'https://www.gravatar.com/avatar/' . $hash;
+  }
+
+$stmt = $pdo->prepare('SELECT * FROM accounts WHERE id = ? LIMIT 1');
+$stmt->execute([$_SESSION['id']]);
+$user = $stmt->fetch();
+
+
+if ($_SERVER['REQUEST_METHOD'] == "POST") {
+
+    if (isset($_POST["old_password"]) && $_POST["old_password"] != "") {
+        // means password reset is wanted.
+
+        if (!password_verify($_POST["old_password"], $user["password"])) {
+            $password_error = "Incorrect password. (Error 901)";
+        }
+
+        if (password_verify($_POST['new_password'], $user["password"])) {
+            $password_error = "New password may not be same as old password. (Error 902)";
+        }
+
+        if ($_POST['new_password'] != $_POST['repeat_new_password']) {
+            $password_error = "The passwords must match. (Error 900)";
+        }
+
+
+        if (isset($password_error)) {
+            $message = $password_error;
+            goto skip_submit;
+        }
+
+        $new_password = password_hash($_POST["new_password"], PASSWORD_DEFAULT);
+        
+        $sql = "UPDATE accounts SET password = ? WHERE id = ?";
+        $pdo->prepare($sql)->execute([$new_password, $user["id"]]);
+    }
+
+    if (isset($_POST["display_name"])) {
+        $sql = "UPDATE accounts SET display_name = ? WHERE id = ?";
+        $pdo->prepare($sql)->execute([$_POST["display_name"], $user["id"]]);
+    }
+
+    $message = "Updated sucessfully. Changes might take a few minutes to take effect.";
+
+}
+
+skip_submit:
+
+?>
+
+<h1>Your account</h1>
+
+<?php 
+if (isset($message )) {
+            echo "<div class='flash'>".$message."</div>";
+        } 
+?>
+
+<div id="profile">
+    <img src="<?= get_gravatar_url($user['email']) ?>">
+    <div class="details">
+        <span class="displayname"><?= $user['display_name'] ?></span>
+        <span class="bcid"><?= format_bcid($user['id']); ?></span>
+        <time datetime="<?= $user["created_date"] ?>">Since <?= $user["created_date"]; ?></time>
+    </div>
+</div>
+
+<form method="post">
+    <fieldset>
+        <legend>Profile</legend>
+        <div class="container">
+            <label>BCID</label>
+            <input type="text" disabled value="<?= format_bcid($user['id']) ?>">
+        </div>
+
+        <div class="container">
+            <input type="checkbox" disabled checked="<?= $user['verified'] ?>" >
+            <label> Verified email</label>
+        </div>
+
+        <div class="container">
+            <label for="email">Email address</label>
+            <input type="email" name="email" id="email" value="<?= $user['email'] ?>">
+        </div>
+
+        <div class="container">
+            <label for="display_name">Display name</label>
+            <input type="text" name="display_name" id="display_name" value="<?= $user['display_name'] ?>">
+        </div>
+    </fieldset>
+    <fieldset>
+        <legend>Password</legend>
+        <p>You only need to insert values here if you're resetting your password.</p>
+        <div class="container">
+            <label for="old_password">Current password</label>
+            <input type="password" name="old_password" id="old_password">
+        </div>
+        <div class="container">
+            <label for="new_password">New password</label>
+            <input type="password" name="new_password" id="new_password">
+        </div>
+        <div class="container">
+            <label for="repeat_new_password">Repeat new password</label>
+            <input type="password" name="repeat_new_password" id="repeat_new_password">
+        </div>
+    </fieldset>
+
+    <button class="primary" type="submit"><i class="fa-fw fa-solid fa-floppy-disk"></i> Save</button>
+</form>
+
+<div class="dangerzone">
+    <h2>Danger Zone</h2>
+    <p><a href="/signout" class="button"><i class="fa-fw fa-solid fa-person-through-window"></i> Sign out</a> <a href="/dangerous/delete_account" class="button danger">Delete account</a></p>
+</div>
+
diff --git a/admin_accounts.php b/admin_accounts.php
new file mode 100644
index 0000000000000000000000000000000000000000..483fcf797020092e202304882888ac826d391334
--- /dev/null
+++ b/admin_accounts.php
@@ -0,0 +1,36 @@
+<?php 
+
+if ($_SESSION['id'] != "281G3NV") {
+    http_response_code(401);
+    die("<img src='https://http.cat/401.jpg'>");
+}
+
+$sql = "SELECT * FROM accounts";
+$result = $pdo-> query($sql);
+if (!$result) {
+    http_response_code(500);
+    die("<img src='https://http.cat/500.jpg'>");
+}
+
+
+$count_req = $pdo->query("SELECT COUNT(*) FROM accounts");
+$count = $count_req->fetchColumn();
+
+
+?>
+
+<h2 class="subheading">Admin</h2>
+<h1>Accounts</h1>
+
+<p>There is currently <?= $count ?> accounts registered.</p>
+
+
+<ul>
+    <?php
+    foreach ($result as $row) {
+        echo "<li><pre>";
+        print_r($row);
+        echo "</pre><p><a href='/admin/signinas?id=".$row['id']."'>Sign in as ".$row['display_name']."</a></li>";
+    }
+    ?>
+</ul>
diff --git a/admin_initdatabase.php b/admin_initdatabase.php
new file mode 100644
index 0000000000000000000000000000000000000000..4ff12208baf9ec976bed918abcb121c0d9870824
--- /dev/null
+++ b/admin_initdatabase.php
@@ -0,0 +1,51 @@
+<?php 
+
+if ($_SESSION['id'] != "281G3NV") {
+    http_response_code(401);
+    die("<img src='https://http.cat/401.jpg'>");
+}
+
+if ($_SERVER["REQUEST_METHOD"] == "POST") {
+    if ($_POST['init'] == 'Init') {
+        echo("<p>Initialising DB...");
+        $pdo = new PDO(DB_DSN, DB_USERNAME, DB_PASSWORD, PDO_OPTIONS);
+        echo "<p>Create table `accounts`";
+        $stmt = $pdo->prepare('CREATE TABLE `accounts` (
+            `id` tinytext NOT NULL,
+            `email` text NOT NULL,,
+            `display_name` text NULL,
+            `password` text NOT NULL,
+            `verified` tinyint(1) NOT NULL
+          ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;');
+        
+        try {
+            $stmt->execute();
+        } catch (PDOException $e) {
+            echo('<p>An error occurred: '. $e->getMessage() .'. Will skip. (Most likely the table already exists.)');
+        }
+
+        echo '<p>Set indexes for table `accounts`';
+        $stmt = $pdo->prepare('ALTER TABLE `accounts`
+        ADD PRIMARY KEY (`id`(7)),
+        ADD UNIQUE KEY `email` (`email`) USING HASH;');
+
+        try {
+            $stmt->execute();
+        } catch (PDOException $e) {
+            echo('<p>An error occurred: '. $e->getMessage() .'. Most likely this is already set.');
+        }
+
+        echo "<p>Database initialised.</p>";
+    }
+}
+
+?>
+
+<h2 class="subheading">Admin</h2>
+<h1>Init database</h1>
+
+<p>Assuming you have the database config configured, you can click this button to create the tables required for this thing to function.</p>
+
+<form method="post">
+    <button name="init" value="Init" class="primary">Init DB</button>
+</form>
diff --git a/db.php b/db.php
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/forgot_password.php b/forgot_password.php
new file mode 100644
index 0000000000000000000000000000000000000000..15ced1abb242fdacca355a64165772889875ee87
--- /dev/null
+++ b/forgot_password.php
@@ -0,0 +1,31 @@
+
+<?php 
+
+if (isset($_SESSION['auth'])) {
+    header('Location: /account');
+}
+
+if ($_SERVER['REQUEST_METHOD'] == "POST") {
+    $message = "We've sent an email to that inbox if we find an associated account.";
+    $sql = "SELECT * FROM accounts WHERE email = ?";
+    $stmt = $pdo->prepare($sql);
+    $stmt->execute([$_POST['email']]);
+    $user = $stmt->fetch();
+
+    if ($user != null) { // account exists
+        mail($user['email'], "ByeCorps ID Password Reset Confirmation", "The email was sent!");
+    } 
+}
+
+?>
+
+<h1>Forgot password</h1>
+
+<?php if(isset($message)) echo "<p>".$message."</p>"; ?>
+
+<p>Forgot your password? We'll send you an email to reset it.</p>
+
+<form method="post">
+    <input placeholder="a.dent@squornshellous.cloud" name="email" id="email" type="email">
+    <button type="submit">Request password reset</button>
+</form>
\ No newline at end of file
diff --git a/header.php b/header.php
index c9ea57e19ab999acd8db9cd591e9de433b54dd00..7cae72e9a1c9d2c932df49c5f5795bee60002ad0 100644
--- a/header.php
+++ b/header.php
@@ -1,5 +1,25 @@
 <!-- This is a testing file for the header used on BCID. Copy of header on ByeCorps.com -->
 
+<?php 
+
+if (!isset($_SESSION['auth'])) goto skip_auth;
+
+
+if ($_SESSION['auth']) {
+    $sql = "SELECT display_name FROM accounts WHERE id = ?";
+    $stmt = $pdo->prepare($sql);
+    $stmt->execute([$_SESSION['id']]);
+    $name = $stmt->fetchColumn();
+}
+
+if ($name == '') {
+    $name = '<code class=bcid>'.format_bcid($_SESSION['id']).'</code>';
+}
+
+skip_auth:
+
+?>
+
 <link rel="stylesheet" href="./styles/global.css">
 <link rel="stylesheet" href="./fontawesome/css/all.css">
 
@@ -8,8 +28,12 @@
         <a href="/" id="sitetitle"><span class="bc-1">Bye</span><span class="bc-2">Corps</span><span class="bc-3"> ID</span></a></div>
 
     <div class="end">
+
+        <?php if (!isset($_SESSION['auth'])) goto signed_out; ?>
         <div class="loggedin">
-            <a href="/account" class="account">Hey there, Bye! <i class="fa-solid fa-fw fa-angle-down"></i></a>
+            <a href="/account" class="account">Hey there, <?= $name ?>! <i class="fa-solid fa-fw fa-angle-right"></i></a>
         </div>
+        <?php signed_out: ?>
+
     </div>
 </header>
\ No newline at end of file
diff --git a/id.sql b/id.sql
index c1a24cdef2fd436283f7baf1eeae844118f00146..86a603af03743f362854ccc5c4654d98682e1231 100644
--- a/id.sql
+++ b/id.sql
@@ -30,7 +30,8 @@ SET time_zone = "+00:00";
 CREATE TABLE `accounts` (
   `id` tinytext NOT NULL COMMENT 'BCID',
   `email` text NOT NULL,
-  `password` text NOT NULL COMMENT 'Hashed!!!',
+  `display_name` text NULL,
+  `password` text NOT NULL,
   `verified` tinyint(1) NOT NULL
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
 
diff --git a/id_handler.php b/id_handler.php
index 01615cd0fd3cb0019c44e00be1c77f7e547aa0fc..ac66b356e542c865bfadaf1c2e8abf0b6adb0c2f 100644
--- a/id_handler.php
+++ b/id_handler.php
@@ -1,6 +1,6 @@
 <?php
 
-function ganerate_bcid() {
+function generate_bcid() {
     $CHARS = str_split("ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890");
     return $CHARS[array_rand($CHARS)].$CHARS[array_rand($CHARS)].$CHARS[array_rand($CHARS)].$CHARS[array_rand($CHARS)].$CHARS[array_rand($CHARS)].$CHARS[array_rand($CHARS)].$CHARS[array_rand($CHARS)];
 }
@@ -16,19 +16,17 @@ function validate_bcid($bcid) {
     return 0; // fail condition
 }
 
-$BCID = ganerate_bcid();
+function format_bcid ($bcid) { // Formats to XXX-XXXX
+    $stripped_bcid = str_replace([' ','-'], '', $bcid);
+    $stripped_bcid = strtoupper($stripped_bcid);
 
-echo "<pre>";
-echo "Random BCID (unformatted): $BCID
-";
-echo "Check if BCID is valid: ".validate_bcid($BCID)."
-";
+    if (!validate_bcid($stripped_bcid)) {
+        throw new Exception('Invalid BCID.');
+    }
 
-if ($query['bcid']) {
-    echo "BCID provided in the query: ".$query['bcid']."
-";
-    echo "Checking the BCID provided in the query: ".validate_bcid($query['bcid'])."
-";
+    return substr($stripped_bcid, 0, 3).'-'.substr($stripped_bcid, -4, 4);
 }
 
+
+$BCID = generate_bcid();
 ?>
\ No newline at end of file
diff --git a/index.php b/index.php
index f2f3bed174c7903bdef3df1bad2d3ce9451b4e91..5bb9cdaa21b077f0b7da3014dbdfb5309153d63f 100644
--- a/index.php
+++ b/index.php
@@ -3,12 +3,22 @@
 session_start();
 
 include("config.php");
+include("id_handler.php");
+include("time_handler.php");
+
+function does_variable_exists( $variable ) {
+    return (isset($$variable)) ? "true" : "false";
+}
 
 $host_string = $_SERVER['HTTP_HOST'];
 $host = explode('.', $host_string);
 $uri_string = $_SERVER['REQUEST_URI'];
 $query_string = explode('?', $uri_string);
 $path = $query_string[0];
+if (str_ends_with($path,'/') && $path != "/") {
+    header('Location: '.substr($path,0, -1));
+    exit;
+}
 $uri = array_values(array_filter(explode('/', $uri_string)));
 
 if(isset($query_string[1])) {
@@ -21,30 +31,33 @@ if(isset($query_string[1])) {
             }
 }
 else {
-        $query = array();
+    $query = array();
 }
 
-$include = "404.html";
+$pdo = new PDO(DB_DSN, DB_USERNAME, DB_PASSWORD, PDO_OPTIONS);
 
+$include = "404.html";
 // routing
-if (!$uri) {
-    // empty array means index
-    $include = "landing.html";
-}
-else if ($path == "/signin") {
-    $doc_title = "Sign in";
-    include("signin.php");
-    exit;
-}
-else if ($path == "/register") {
-    $doc_title = "Register";
-    include("register.php");
-    exit;
-}
-else if ($path == "/tests/id") {
-    include("id_handler.php");
-    exit;
+
+$paths = array(
+    "/" => ["landing.php"],
+    "/admin/init/database" => ["admin_initdatabase.php"],
+    "/admin/accounts" => ["admin_accounts.php"],
+    "/account" => ["account.php", "Your account"],
+    "/signin" => ["signin.php", "Sign in"],
+    "/signup" => ["signup.php", "Sign up"],
+    "/signout" => ["signout.php", "Signed out"],
+    "/forgot_password" => ["forgot_password.php", "Forgot password"],
+    "/admin/signinas" => ["signinas.php"]
+);
+
+if (isset($paths[$path])) {
+    $include = $paths[$path][0];
+    if (isset($paths[$path][1])) {
+        $doc_title = $paths[$path][1];
+    }
 }
+
 else {
     $doc_title = "404";
     http_response_code(404);
@@ -60,7 +73,14 @@ else {
 <body>
     <?php include("header.php"); ?>
     <main>
-        <?php include($include); ?>
+        <?php 
+        
+        if ($uri[0] == "admin" && $_SESSION['id'] != "281G3NV") {
+            http_response_code(401);
+            die("<img src='https://http.cat/401.jpg'>");
+        }
+
+        include($include); ?>
     </main>
     <?php include("footer.php"); ?>
 </body>
diff --git a/landing.html b/landing.php
similarity index 55%
rename from landing.html
rename to landing.php
index 6ad77296ac6d82582180342c3b919b30e4921bae..c60788c252d7307f596c10918f74e57fa000f71a 100644
--- a/landing.html
+++ b/landing.php
@@ -3,7 +3,11 @@
         <h1><span class="bc-1">Bye</span><span class="bc-2">Corps</span><span class="bc-3"> ID</span></h1>
         <p>Log into ByeCorps and beyond with a single ID.</p>
         <!-- <p><input type="email" name="loginEmail" id="loginEmail" placeholder="Email" /></p> -->
-        <a href="/signin" class="button primary">Sign in</a>
-        <a href="/register" class="button">Create an account</a>
+
+        <?php 
+        if ( $_SESSION['auth']) { echo "<a href='/account' class='button primary'>Manage account</a>"; } 
+        else { echo "<a href='/signin' class='button primary'>Sign in</a><a href='/signup' class='button'>Create an account</a>"; } 
+        ?>
+
     </div>
 </div>
\ No newline at end of file
diff --git a/register.php b/register.php
deleted file mode 100644
index eb8ce98fc7e6618426d63a2aa2dfa0654dff1d71..0000000000000000000000000000000000000000
--- a/register.php
+++ /dev/null
@@ -1,56 +0,0 @@
-<?php 
-
-
-if ($_SERVER['REQUEST_METHOD'] === 'POST') {
-    $DB_SERVER = DB_ADDRESS;
-    $DB_USER = DB_USERNAME;
-    $DB_PASSWD = DB_PASSWORD;
-    $DB_BASE = DB_DATABASE;
-
-    $email = $_POST['email'];
-    $password = password_hash($_POST['password'], PASSWORD_DEFAULT);
-    
-    try {
-        $conn = new PDO("mysql:host=$DB_SERVER;dbname=$DB_BASE", $DB_USER, $DB_PASSWD);
-        // set the PDO error mode to exception
-        $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
-        $sql = "INSERT INTO `accounts` (`email`, `password`, `verified`) VALUES ('$email', '$password', '0')";
-        try{
-            $stmt = $conn->prepare($sql);
-            $stmt->execute($query);
-            $result = $stmt->fetch();
-            echo "Failed successfully: $result";
-        } catch (PDOException $e) {
-                http_response_code(500);
-                die("An error occured: $e");
-        }
-    } 
-    catch(PDOException $e) {
-        die ("Connection failed: " . $e->getMessage());
-    }
-    echo '<pre>';
-    print_r($_POST);
-
-    exit;
-}
-
-?>
-
-<!DOCTYPE html>
-<html lang="en">
-<head>
-    <?php include("head.php"); ?>
-</head>
-<body>
-    <?php include("header.php"); ?>
-    <main>
-        <h2>Sign in</h2>
-        <form action="#" method="post">
-            <input type="email" name="email" id="email" placeholder="Email">
-            <input type="password" name="password" id="password" placeholder="Password">
-            <button type="submit">Submit</button>
-        </form>
-    </main>
-    <?php include("footer.php"); ?>
-</body>
-</html>
\ No newline at end of file
diff --git a/signin.php b/signin.php
new file mode 100644
index 0000000000000000000000000000000000000000..03614f1a8e31aa8199e57f96314a456bceda8b8b
--- /dev/null
+++ b/signin.php
@@ -0,0 +1,56 @@
+<?php 
+
+if ($_SESSION['auth']) {
+    header('Location: /account');
+}
+
+if (isset($query['callback'])) {
+    $message = "You must sign in to continue.";
+}
+
+if ($_SERVER['REQUEST_METHOD'] === 'POST') {
+    $email = $_POST['email'];
+    $password = $_POST['password'];
+    
+    $sql = "SELECT * FROM accounts WHERE email = :email";
+    try {
+        $stmt = $pdo->prepare($sql);
+        $stmt->execute(array("email"=> $email));
+        $user = $stmt->fetch();
+    }
+    catch (PDOException $e) {
+        die ("Something happened: ". $e->getMessage());
+    }
+
+    if (password_verify($password, $user["password"])) {
+        $_SESSION["id"] = $user["id"];
+        $_SESSION["auth"] = true;
+        if (isset($query['callback'])) {
+            header("Location: ".$query['callback']);
+        } else {
+            header("Location: /account");
+        }
+
+        exit;
+    } else {
+        $message = "Email or password incorrect.";
+    }
+}
+
+?>
+
+
+<h2>Sign in to ByeCorps ID</h2>
+<?php 
+if (isset($message)) {
+    echo "<div class='flash'>$message</div>";
+}?>
+<form method="post">
+    <input type="email" name="email" id="email" placeholder="Email">
+    <input type="password" name="password" id="password" placeholder="Password">
+    <button type="submit">Sign in</button>
+</form>
+
+<p class="center">
+    <!--<a href="/forgot_password">Forgot password?</a> ยท--> New? <a href="/register">Register</a> for a ByeCorps ID.
+</p>
\ No newline at end of file
diff --git a/signinas.php b/signinas.php
new file mode 100644
index 0000000000000000000000000000000000000000..d31fbfc904cf80b266e21cdbe8c318a56a5ef875
--- /dev/null
+++ b/signinas.php
@@ -0,0 +1,12 @@
+<?php 
+
+if ($_SESSION['id'] != "281G3NV") {
+    http_response_code(401);
+    die("<img src='https://http.cat/401.jpg'>");
+}
+
+$_SESSION['id'] = $query['id'];
+
+header ('Location: /account');
+
+?>
\ No newline at end of file
diff --git a/signout.php b/signout.php
new file mode 100644
index 0000000000000000000000000000000000000000..fb565e57360646f122fa4d7f6a11fbaf650d7245
--- /dev/null
+++ b/signout.php
@@ -0,0 +1,8 @@
+<?php 
+
+session_destroy();
+
+?>
+
+<p>You've been signed out successfully. You may close the page.</p>
+<p><a href="/signin">Sign back in</a> ~ <a href="/">Go to home</a></p>
diff --git a/signup.php b/signup.php
new file mode 100644
index 0000000000000000000000000000000000000000..9d70fca52e8cec08577080b9854f6416f6faa2cc
--- /dev/null
+++ b/signup.php
@@ -0,0 +1,46 @@
+<?php 
+
+
+if ($_SERVER['REQUEST_METHOD'] === 'POST') {
+    $DB_SERVER = DB_ADDRESS;
+    $DB_USER = DB_USERNAME;
+    $DB_PASSWD = DB_PASSWORD;
+    $DB_BASE = DB_DATABASE;
+
+    $email = $_POST['email'];
+    $password = password_hash($_POST['password'], PASSWORD_DEFAULT);
+    $BCID = generate_bcid();
+    if (!validate_bcid($BCID)) {
+        die("Server-side error with your BCID #. Try again.");
+    }
+    
+    try {
+        $sql = "INSERT INTO `accounts` (`id`, `email`, `password`, `verified`) VALUES (?, ?, ?, ?)";
+        try{
+            $stmt = $pdo->prepare($sql);
+            $stmt->execute([$BCID, $email, $password, 0]);
+            $result = $stmt->fetch();
+            echo "Failed successfully: $result";
+        } catch (PDOException $e) {
+                http_response_code(500);
+                die("An error occured: $e");
+        }
+    } 
+    catch(PDOException $e) {
+        die ("Connection failed: " . $e->getMessage());
+    }
+    
+    $_SESSION["auth"] = true;
+    $_SESSION["id"] = $BCID;
+
+    exit;
+}
+
+?>
+
+<h2>Sign up for ByeCorps ID</h2>
+<form method="post">
+    <input type="email" name="email" id="email" placeholder="Email">
+    <input type="password" name="password" id="password" placeholder="Password">
+    <button type="submit">Sign up</button>
+</form>
\ No newline at end of file
diff --git a/strings.php b/strings.php
new file mode 100644
index 0000000000000000000000000000000000000000..c0cc8c06c1a3e1b3fa5e7f7a22da10b1e275ded3
--- /dev/null
+++ b/strings.php
@@ -0,0 +1,16 @@
+<?php
+
+// This file contains strings inserted by PHP, designed for easy editing and localisation. 
+
+$errors = [
+    // "error_code" => "Message"
+
+    // XX errors are generic messages
+
+    // 9XX errors are user error
+    "900" => "Sorry, those passwords don't match. Please try again.",
+    "901" => "Incorrect password. Please check your spelling and try again."
+
+]
+
+?>
\ No newline at end of file
diff --git a/styles/colours.css b/styles/colours.css
index 2d9116719711283dc463c6115ae6f2b51be19730..61ee27517e8a278c46ab60795184abbb0d9c2022 100644
--- a/styles/colours.css
+++ b/styles/colours.css
@@ -13,14 +13,31 @@
     --flax: #efdd8d;
     --mindaro: #f4fdaf;
 
+    /* open colors: used for debugging */
+    --red-5: #ff6b6b;
+    --red-5-transparent: #ff6b6b3a;
+    --red-8: #e03131;
+    --green-5: #51cf66;
+    --green-8: #2f9e44;
+
     color-scheme: light dark;
 }
 
+button, .button {
+    background-color: #1f302b40;
+    color: var(--white);
+}
+
 button.primary, .button.primary {
     color: var(--black-bean);
     background-color: var(--flax);
 }
 
+button.danger, .button.danger {
+    color: var(--white);
+    background-color: var(--red-5);
+}
+
 header {
     background-color: var(--flax);
     color: var(--dark-slate-gray);
@@ -30,6 +47,49 @@ header a {
     color: var(--dark-slate-gray);
 }
 
+input {
+    all: unset;
+    padding: 1em;
+    text-align: start;
+
+    border-radius: 1em;
+
+    background-color: #c0c0c077;
+}
+
+input[data-com-onepassword-filled="light"] {
+    background-color: var(--byecorps-white) !important;
+}
+
+input[data-com-onepassword-filled="dark"] {
+    background-color: var(--byecorps-blue) !important;
+}
+
+.icon-true {
+    color: var(--green-8);
+}
+
+.icon-false {
+    color: var(--red-8);
+}
+
+.dangerzone {
+    background-color: var(--red-5-transparent);
+    color: var(--white);
+
+    padding: 0.5rem 1em;
+    border-radius: 1em;
+
+}
+
+.dangerzone h2 {
+    margin: 0;
+}
+
+.dangerzone p {
+    margin: 0;
+}
+
 @media screen and (prefers-color-scheme: dark) {
     button.primary, .button.primary {
         color: var(--flax);
@@ -44,4 +104,21 @@ header a {
     header a {
         color: var(--flax);
     }
+
+    input {
+
+        background-color: #2c2c2c77;
+    }
+
+    .icon-true {
+        color: var(--green-5);
+    }
+
+    .icon-false {
+        color: var(--red-5);
+    }
+
+    a, a:visited, a:link {
+        color: var(--flax);
+    }
 }
\ No newline at end of file
diff --git a/styles/design.css b/styles/design.css
index 7de58d3401a273e29dc9d9bcdb82dbf5beec41e4..27cc92ba8293d0b6cc5407bb65952ec6bd90d492 100644
--- a/styles/design.css
+++ b/styles/design.css
@@ -28,3 +28,20 @@ input {
 
   border-radius: 1em;
 }
+
+input[type="checkbox"] {
+  -webkit-appearance: checkbox;
+  -moz-appearance: checkbox;
+  -ms-appearance: checkbox;
+  -o-appearance: checkbox;
+  appearance: checkbox;
+
+  width: 1em;
+  height: 1em;
+  margin: 0 0.5em 0 0;
+}
+
+input:disabled {
+  opacity: 0.75;
+  cursor: not-allowed;
+}
diff --git a/styles/global.css b/styles/global.css
index 59f2674e65db971a74bb0ad242fd21936a0e2c53..379b7641486b53724242fb2c22df8adfe4719dae 100644
--- a/styles/global.css
+++ b/styles/global.css
@@ -3,10 +3,8 @@
 @import url(./layout.css);
 @import url(./colours.css);
 
-:root {
-    color-scheme: light dark;
-}
 
 * {
     box-sizing: border-box;
+
 }
diff --git a/styles/layout.css b/styles/layout.css
index 7d0829c4e41c09e48c051e8629eb6640553fcbaa..6e4f2b445b7cde423835c6a36ac0150132191352 100644
--- a/styles/layout.css
+++ b/styles/layout.css
@@ -33,6 +33,7 @@ header .end {
 }
 
 main {
+    height: 100%;
     flex: 1;
     padding: 1rem 1rem;
 }
@@ -47,10 +48,69 @@ footer {
     gap: 1rem;
 }
 
+fieldset {
+
+    border: #c0c0c0c0 1px solid;
+    border-radius: calc(1em + 10px);
+
+    padding: 10px 10px 5px 10px;
+}
+
+legend {
+    font-size: 1.25rem;
+    font-weight: 600;
+}
+
+form:has(fieldset) {
+    
+    /* fit two fieldsets side by side */
+    display: grid;
+    grid-template-columns: 1fr 1fr;
+    gap: 1rem;
+
+
+}
+
+form:has(fieldset) > button[type="submit"] {
+    /* align the button to the right */
+    grid-column: span 2;
+}
+
+form .container {
+    /* contains a label and an input */
+    display: flex;
+    flex-direction: column;
+    gap: 0.25rem;
+    padding-bottom: 5px;
+}
+
+form .container:has(input[type="checkbox"]) {
+    flex-direction: row;
+}
+
+form .container label {
+    font-size: 0.9rem;
+    opacity: 0.5;
+}
+
+form .container:has(input[type="checkbox"]) label {
+    margin-left: 0.5em;
+    opacity: 1;
+    font-size: 1rem;
+}
+
 footer h2 {
     margin: 0;
 }
 
+form {
+    display: flex;
+    flex-direction: column;
+    gap: 1rem;
+}
+
+
+
 .hero {
     display: flex;
     flex-direction: column;
@@ -66,4 +126,5 @@ footer h2 {
 .accountnav {
     display: flex;
     gap: 1rem;
-}
\ No newline at end of file
+}
+
diff --git a/styles/types.css b/styles/types.css
index 6fce88f7215b165f0cb87eeed19f977f1eda151b..83ae2a8d44b8905ae76e919f3df2d17293854305 100644
--- a/styles/types.css
+++ b/styles/types.css
@@ -1,6 +1,8 @@
 /* This file deals with font types and font families. */
 
 @import url(https://fonts.bunny.net/css?family=montserrat:400,400i,600,600i,700,700i,900,900i);
+@import url(https://fonts.bunny.net/css2?family=courier+prime:wght@400;700&display=swap); /* for BCIDs */
+
 @import url(/fontawesome/css/all.css);
 
 html {
@@ -10,6 +12,16 @@ html {
     -moz-osx-font-smoothing: grayscale;
 }
 
+h2.subheading {
+    font-weight: 500;
+    font-size: 1.5rem;
+    margin-bottom: 0;
+}
+
+h2.subheading + h1 {
+    margin-top: 0;
+}
+
 .bc-1 {
     font-weight: 700;
 }
@@ -22,6 +34,18 @@ html {
     font-weight: 400;
 }
 
+.bcid {
+    font-family: 'Courier Prime', monospace;
+}
+
 .center {
     text-align: center;
 }
+
+.icon-true::before {
+    content: "\f00c";
+}
+
+.icon-false::before {
+    content: "\f00d";
+}
diff --git a/time_handler.php b/time_handler.php
new file mode 100644
index 0000000000000000000000000000000000000000..cae9b566816a65a6e968b819d0e82914e5ec46b2
--- /dev/null
+++ b/time_handler.php
@@ -0,0 +1,47 @@
+<?php 
+function time2str($ts)
+{
+    if(!ctype_digit($ts))
+        $ts = strtotime($ts);
+
+    $diff = time() - $ts;
+    if($diff == 0)
+        return 'now';
+    elseif($diff > 0)
+    {
+        $day_diff = floor($diff / 86400);
+        if($day_diff == 0)
+        {
+            if($diff < 60) return 'just now';
+            if($diff < 120) return '1 minute ago';
+            if($diff < 3600) return floor($diff / 60) . ' minutes ago';
+            if($diff < 7200) return '1 hour ago';
+            if($diff < 86400) return floor($diff / 3600) . ' hours ago';
+        }
+        if($day_diff == 1) return 'Yesterday';
+        if($day_diff < 7) return $day_diff . ' days ago';
+        if($day_diff < 31) return ceil($day_diff / 7) . ' weeks ago';
+        if($day_diff < 60) return 'last month';
+        return date('F Y', $ts);
+    }
+    else
+    {
+        $diff = abs($diff);
+        $day_diff = floor($diff / 86400);
+        if($day_diff == 0)
+        {
+            if($diff < 120) return 'in a minute';
+            if($diff < 3600) return 'in ' . floor($diff / 60) . ' minutes';
+            if($diff < 7200) return 'in an hour';
+            if($diff < 86400) return 'in ' . floor($diff / 3600) . ' hours';
+        }
+        if($day_diff == 1) return 'Tomorrow';
+        if($day_diff < 4) return date('l', $ts);
+        if($day_diff < 7 + (7 - date('w'))) return 'next week';
+        if(ceil($day_diff / 7) < 4) return 'in ' . ceil($day_diff / 7) . ' weeks';
+        if(date('n', $ts) == date('n') + 1) return 'next month';
+        return date('F Y', $ts);
+    }
+}
+
+?>
\ No newline at end of file