summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMorgana <Morgana@icolotl.com>2026-09-25 14:19:20 -0500
committerMorgana <Morgana@icolotl.com>2026-09-25 14:19:20 -0500
commit7fc188b0a4d73856c05eacc9bdf2a1561505a8d6 (patch)
treead2b4132865432a1e8e321a033e62b1838c3dc94
Initial Commit
-rw-r--r--.gitignore4
-rw-r--r--app.py126
-rw-r--r--static/img/background.pngbin0 -> 316777 bytes
-rw-r--r--static/img/bgcropped.pngbin0 -> 359479 bytes
-rw-r--r--static/img/bgcropped.webpbin0 -> 189264 bytes
-rw-r--r--static/img/eguide.gifbin0 -> 2074 bytes
-rw-r--r--static/img/gitrepos.gifbin0 -> 2134 bytes
-rw-r--r--static/img/photography.webpbin0 -> 59236 bytes
-rw-r--r--static/montserrat/Montserrat-Italic-VariableFont_wght.ttfbin0 -> 701156 bytes
-rw-r--r--static/montserrat/Montserrat-VariableFont_wght.ttfbin0 -> 688600 bytes
-rw-r--r--static/montserrat/OFL.txt93
-rw-r--r--static/msmadi/MsMadi-Regular.ttfbin0 -> 142360 bytes
-rw-r--r--static/msmadi/OFL.txt93
-rw-r--r--static/style/hyde.css165
-rw-r--r--static/style/index.css142
-rw-r--r--static/style/login.css18
-rw-r--r--static/style/style.css124
-rw-r--r--templates/base.html47
-rw-r--r--templates/hyde.html102
-rw-r--r--templates/index.html59
-rw-r--r--templates/login.html19
21 files changed, 992 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..f468089
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,4 @@
+__pycache__/
+.venv/
+akasha.db
+config.json \ No newline at end of file
diff --git a/app.py b/app.py
new file mode 100644
index 0000000..79ad458
--- /dev/null
+++ b/app.py
@@ -0,0 +1,126 @@
+import json
+from hashlib import scrypt
+from os import urandom
+from hmac import compare_digest
+import sqlite3
+
+from flask import (
+ Flask,
+ render_template,
+ request,
+ redirect,
+ url_for,
+ session,
+ g,
+ flash,
+)
+from werkzeug.exceptions import HTTPException
+
+SCRYPT_PARAMS = {"n": 16384, "r": 8, "p": 1}
+HEX_CHARS = set("0123456789ABCDEF")
+
+
+def get_db():
+ if "db" not in g:
+ g.db = sqlite3.connect("akasha.db", detect_types=sqlite3.PARSE_DECLTYPES)
+ g.db.row_factory = sqlite3.Row
+ return g.db
+
+
+def teardown(e=None):
+ if (db := g.pop("db", None)) is not None:
+ db.close()
+
+
+app = Flask(__name__)
+with open("./config.json", "r", encoding="utf-8") as file:
+ config = json.load(file)
+ app.config["SECRET_KEY"] = config["fsk"]
+ LIGHT_URL = f"http://192.168.1.10/api/{config['light']}"
+ del config
+ app.teardown_appcontext(teardown)
+
+
+@app.errorhandler(HTTPException)
+def handle_bad_request(e):
+ if request.endpoint != "static":
+ # TODO: Create an actual error page.
+ if "username" not in session:
+ flash("Guest access is temporarily restricted. Please log in to continue.")
+ return redirect(url_for("login"))
+ flash(f"Error {e.code}: {e.name}")
+ flash("You have been redirected to the main page.")
+ return redirect(url_for("index"))
+ return e
+
+
+@app.route("/")
+def index():
+ db = get_db()
+ cur = db.cursor()
+ cur.execute("SELECT * FROM news ORDER BY id DESC LIMIT 1")
+ results = cur.fetchone()
+ return render_template("index.html", news=results)
+
+
+@app.route("/login", methods=["GET", "POST"])
+def login():
+ db = get_db()
+ if request.method == "POST":
+ username = request.form.get("username")
+ password = request.form.get("password")
+ if not username or not password:
+ flash("Error: Empty username or password.")
+ return redirect(url_for("login"))
+ if request.form.get("register") == "1":
+ cur = db.cursor()
+ cur.execute("SELECT 1 FROM users WHERE username=?", (username,))
+ if cur.fetchone():
+ flash("Error: User already exists.")
+ return redirect(url_for("login"))
+ salt = urandom(32)
+ hash = scrypt(password.encode("utf-8"), salt=salt, **SCRYPT_PARAMS)
+ cur.execute(
+ "INSERT INTO users (username, hash, salt) VALUES (?, ?, ?)",
+ (username, hash, salt),
+ )
+ flash("Success: User registered.")
+ db.commit()
+ else:
+ cur = db.cursor()
+ cur.execute("SELECT hash, salt FROM users WHERE username=?", (username,))
+ results = cur.fetchone()
+ if not results:
+ flash("Error: Invalid username or password.")
+ return redirect(url_for("login"))
+ expected_hash, salt = results
+ actual_hash = scrypt(password.encode("utf-8"), salt=salt, **SCRYPT_PARAMS)
+ if not compare_digest(expected_hash, actual_hash):
+ flash("Error: Invalid username or password.")
+ return redirect(url_for("login"))
+ session["username"] = username
+ flash(f"Success: Logged in as {username}.")
+ return redirect(url_for("index"))
+ return render_template("login.html")
+
+
+@app.route("/logout")
+def logout():
+ if "username" in session:
+ del session["username"]
+ flash("Success: You have been logged out.")
+ return redirect(url_for("index"))
+
+
+@app.route("/hyde")
+def hydematch():
+ if "username" not in session:
+ flash(
+ "The Drosera Springs Wrestling Database is only available to logged-in users."
+ )
+ return redirect(url_for("login"))
+ db = get_db()
+ cur = db.cursor()
+ cur.execute("SELECT * FROM matches ORDER BY id DESC")
+ results = cur.fetchall()
+ return render_template("hyde.html", matches=results)
diff --git a/static/img/background.png b/static/img/background.png
new file mode 100644
index 0000000..1369bd3
--- /dev/null
+++ b/static/img/background.png
Binary files differ
diff --git a/static/img/bgcropped.png b/static/img/bgcropped.png
new file mode 100644
index 0000000..fbe0569
--- /dev/null
+++ b/static/img/bgcropped.png
Binary files differ
diff --git a/static/img/bgcropped.webp b/static/img/bgcropped.webp
new file mode 100644
index 0000000..29c92f6
--- /dev/null
+++ b/static/img/bgcropped.webp
Binary files differ
diff --git a/static/img/eguide.gif b/static/img/eguide.gif
new file mode 100644
index 0000000..3d1985a
--- /dev/null
+++ b/static/img/eguide.gif
Binary files differ
diff --git a/static/img/gitrepos.gif b/static/img/gitrepos.gif
new file mode 100644
index 0000000..72c24dc
--- /dev/null
+++ b/static/img/gitrepos.gif
Binary files differ
diff --git a/static/img/photography.webp b/static/img/photography.webp
new file mode 100644
index 0000000..7085279
--- /dev/null
+++ b/static/img/photography.webp
Binary files differ
diff --git a/static/montserrat/Montserrat-Italic-VariableFont_wght.ttf b/static/montserrat/Montserrat-Italic-VariableFont_wght.ttf
new file mode 100644
index 0000000..76e3f9d
--- /dev/null
+++ b/static/montserrat/Montserrat-Italic-VariableFont_wght.ttf
Binary files differ
diff --git a/static/montserrat/Montserrat-VariableFont_wght.ttf b/static/montserrat/Montserrat-VariableFont_wght.ttf
new file mode 100644
index 0000000..451e692
--- /dev/null
+++ b/static/montserrat/Montserrat-VariableFont_wght.ttf
Binary files differ
diff --git a/static/montserrat/OFL.txt b/static/montserrat/OFL.txt
new file mode 100644
index 0000000..8e618c8
--- /dev/null
+++ b/static/montserrat/OFL.txt
@@ -0,0 +1,93 @@
+Copyright 2024 The Montserrat.Git Project Authors (https://github.com/JulietaUla/Montserrat.git)
+
+This Font Software is licensed under the SIL Open Font License, Version 1.1.
+This license is copied below, and is also available with a FAQ at:
+https://openfontlicense.org
+
+
+-----------------------------------------------------------
+SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
+-----------------------------------------------------------
+
+PREAMBLE
+The goals of the Open Font License (OFL) are to stimulate worldwide
+development of collaborative font projects, to support the font creation
+efforts of academic and linguistic communities, and to provide a free and
+open framework in which fonts may be shared and improved in partnership
+with others.
+
+The OFL allows the licensed fonts to be used, studied, modified and
+redistributed freely as long as they are not sold by themselves. The
+fonts, including any derivative works, can be bundled, embedded,
+redistributed and/or sold with any software provided that any reserved
+names are not used by derivative works. The fonts and derivatives,
+however, cannot be released under any other type of license. The
+requirement for fonts to remain under this license does not apply
+to any document created using the fonts or their derivatives.
+
+DEFINITIONS
+"Font Software" refers to the set of files released by the Copyright
+Holder(s) under this license and clearly marked as such. This may
+include source files, build scripts and documentation.
+
+"Reserved Font Name" refers to any names specified as such after the
+copyright statement(s).
+
+"Original Version" refers to the collection of Font Software components as
+distributed by the Copyright Holder(s).
+
+"Modified Version" refers to any derivative made by adding to, deleting,
+or substituting -- in part or in whole -- any of the components of the
+Original Version, by changing formats or by porting the Font Software to a
+new environment.
+
+"Author" refers to any designer, engineer, programmer, technical
+writer or other person who contributed to the Font Software.
+
+PERMISSION & CONDITIONS
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of the Font Software, to use, study, copy, merge, embed, modify,
+redistribute, and sell modified and unmodified copies of the Font
+Software, subject to the following conditions:
+
+1) Neither the Font Software nor any of its individual components,
+in Original or Modified Versions, may be sold by itself.
+
+2) Original or Modified Versions of the Font Software may be bundled,
+redistributed and/or sold with any software, provided that each copy
+contains the above copyright notice and this license. These can be
+included either as stand-alone text files, human-readable headers or
+in the appropriate machine-readable metadata fields within text or
+binary files as long as those fields can be easily viewed by the user.
+
+3) No Modified Version of the Font Software may use the Reserved Font
+Name(s) unless explicit written permission is granted by the corresponding
+Copyright Holder. This restriction only applies to the primary font name as
+presented to the users.
+
+4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
+Software shall not be used to promote, endorse or advertise any
+Modified Version, except to acknowledge the contribution(s) of the
+Copyright Holder(s) and the Author(s) or with their explicit written
+permission.
+
+5) The Font Software, modified or unmodified, in part or in whole,
+must be distributed entirely under this license, and must not be
+distributed under any other license. The requirement for fonts to
+remain under this license does not apply to any document created
+using the Font Software.
+
+TERMINATION
+This license becomes null and void if any of the above conditions are
+not met.
+
+DISCLAIMER
+THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
+OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
+COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
+DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
+OTHER DEALINGS IN THE FONT SOFTWARE.
diff --git a/static/msmadi/MsMadi-Regular.ttf b/static/msmadi/MsMadi-Regular.ttf
new file mode 100644
index 0000000..310d480
--- /dev/null
+++ b/static/msmadi/MsMadi-Regular.ttf
Binary files differ
diff --git a/static/msmadi/OFL.txt b/static/msmadi/OFL.txt
new file mode 100644
index 0000000..6947b4f
--- /dev/null
+++ b/static/msmadi/OFL.txt
@@ -0,0 +1,93 @@
+Copyright 2018 The Ms Madi Project Authors (https://github.com/googlefonts/ms-madi)
+
+This Font Software is licensed under the SIL Open Font License, Version 1.1.
+This license is copied below, and is also available with a FAQ at:
+https://openfontlicense.org
+
+
+-----------------------------------------------------------
+SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
+-----------------------------------------------------------
+
+PREAMBLE
+The goals of the Open Font License (OFL) are to stimulate worldwide
+development of collaborative font projects, to support the font creation
+efforts of academic and linguistic communities, and to provide a free and
+open framework in which fonts may be shared and improved in partnership
+with others.
+
+The OFL allows the licensed fonts to be used, studied, modified and
+redistributed freely as long as they are not sold by themselves. The
+fonts, including any derivative works, can be bundled, embedded,
+redistributed and/or sold with any software provided that any reserved
+names are not used by derivative works. The fonts and derivatives,
+however, cannot be released under any other type of license. The
+requirement for fonts to remain under this license does not apply
+to any document created using the fonts or their derivatives.
+
+DEFINITIONS
+"Font Software" refers to the set of files released by the Copyright
+Holder(s) under this license and clearly marked as such. This may
+include source files, build scripts and documentation.
+
+"Reserved Font Name" refers to any names specified as such after the
+copyright statement(s).
+
+"Original Version" refers to the collection of Font Software components as
+distributed by the Copyright Holder(s).
+
+"Modified Version" refers to any derivative made by adding to, deleting,
+or substituting -- in part or in whole -- any of the components of the
+Original Version, by changing formats or by porting the Font Software to a
+new environment.
+
+"Author" refers to any designer, engineer, programmer, technical
+writer or other person who contributed to the Font Software.
+
+PERMISSION & CONDITIONS
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of the Font Software, to use, study, copy, merge, embed, modify,
+redistribute, and sell modified and unmodified copies of the Font
+Software, subject to the following conditions:
+
+1) Neither the Font Software nor any of its individual components,
+in Original or Modified Versions, may be sold by itself.
+
+2) Original or Modified Versions of the Font Software may be bundled,
+redistributed and/or sold with any software, provided that each copy
+contains the above copyright notice and this license. These can be
+included either as stand-alone text files, human-readable headers or
+in the appropriate machine-readable metadata fields within text or
+binary files as long as those fields can be easily viewed by the user.
+
+3) No Modified Version of the Font Software may use the Reserved Font
+Name(s) unless explicit written permission is granted by the corresponding
+Copyright Holder. This restriction only applies to the primary font name as
+presented to the users.
+
+4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
+Software shall not be used to promote, endorse or advertise any
+Modified Version, except to acknowledge the contribution(s) of the
+Copyright Holder(s) and the Author(s) or with their explicit written
+permission.
+
+5) The Font Software, modified or unmodified, in part or in whole,
+must be distributed entirely under this license, and must not be
+distributed under any other license. The requirement for fonts to
+remain under this license does not apply to any document created
+using the Font Software.
+
+TERMINATION
+This license becomes null and void if any of the above conditions are
+not met.
+
+DISCLAIMER
+THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
+OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
+COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
+DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
+OTHER DEALINGS IN THE FONT SOFTWARE.
diff --git a/static/style/hyde.css b/static/style/hyde.css
new file mode 100644
index 0000000..b4c91ef
--- /dev/null
+++ b/static/style/hyde.css
@@ -0,0 +1,165 @@
+html {
+ font-family: Arial, sans-serif;
+ background-color: #171717;
+}
+
+body {
+ margin: 0;
+ padding: 0;
+}
+
+header {
+ margin-top: 1em;
+ background-color: #551515;
+ color: #ffffff;
+ padding-bottom: 0.5em;
+
+ >div {
+ max-width: 70em;
+ margin: auto;
+ padding: 1em;
+ display: flex;
+ flex-direction: row;
+ align-items: end;
+ gap: 1em;
+
+ >div {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ }
+ }
+
+ h1 {
+ letter-spacing: 0.1em;
+ font-size: 3.5em;
+ font-weight: bold;
+ margin: 0;
+ }
+
+ strong {
+ letter-spacing: 0.05em;
+ font-weight: normal;
+ }
+
+ a {
+ color: #aaaaaa;
+ text-decoration: none;
+ font-variant: small-caps;
+ }
+
+ span {
+ flex-grow: 1;
+ }
+}
+
+main {
+ background-color: #fcfcfc;
+ margin: auto;
+ padding: 2em;
+ max-width: 70em;
+}
+
+h2 {
+ padding: 1rem 2rem;
+ margin: 0 -2rem;
+ font-variant: small-caps;
+ background-color: #eeeeee;
+ border: 1px solid #ddd7d7;
+ text-shadow: 0.1rem 0.1rem #DDD;
+}
+
+h3 {
+ font-variant: small-caps;
+ text-shadow: 0.1rem 0.1rem #DDD;
+ color: #444;
+}
+
+hr {
+ border: solid #ddd7d7;
+ border-top: 2px;
+ margin: 2em 0;
+}
+
+footer {
+ font-size: 0.9em;
+ text-align: center;
+ padding: 0.5em;
+ color: #C77;
+}
+
+a {
+ color: #772F18;
+ text-decoration: none;
+}
+
+table {
+ font-size: 0.9em;
+ width: 100%;
+ table-layout: fixed;
+}
+
+.datatable {
+ th {
+ width: 25%;
+ text-align: left;
+ font-weight: normal;
+ }
+}
+
+#matchtable {
+ border-collapse: separate;
+ border-spacing: 0 1px;
+
+ th {
+ text-align: start;
+ }
+
+ th#matchno {
+ width: 3em;
+ }
+
+ th#matchdate {
+ width: 7em;
+ }
+
+ td {
+ padding: 0.25em;
+ }
+
+ tr {
+ background-color: #f0f0f0;
+ }
+
+ tr:first-child {
+ background-color: #cccccc;
+ }
+
+ tr:nth-child(even) {
+ background-color: #e2e2e2;
+ }
+
+ tr>:nth-child(1) {
+ color: #555;
+ text-align: center;
+ }
+
+ strong {
+ color: #772F18;
+ }
+
+ small {
+ font-size: 0.9em;
+ }
+}
+
+@media (max-width: 750px) {
+ html {
+ font-size: 0.7em;
+ }
+
+ header>div {
+ flex-direction: column;
+ align-items: start;
+ }
+} \ No newline at end of file
diff --git a/static/style/index.css b/static/style/index.css
new file mode 100644
index 0000000..bee815d
--- /dev/null
+++ b/static/style/index.css
@@ -0,0 +1,142 @@
+html {
+ background-color: var(--dark-color);
+}
+
+main {
+ background-image: url("/static/img/bgcropped.webp"), linear-gradient(5deg, var(--heavy-color) 30%, var(--light-color));
+ background-color: var(--heavy-color);
+ background-size: cover;
+ aspect-ratio: 2 / 1;
+ box-shadow: 0 -1em 1em var(--heavy-color) inset;
+ display: flex;
+ flex-direction: column;
+}
+
+header {
+ font-size: 3em;
+}
+
+nav {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 1em;
+ justify-content: center;
+ align-content: start;
+ flex-grow: 2;
+ max-width: 75em;
+ margin: auto;
+
+ >a {
+ flex-grow: 0;
+ flex-shrink: 0;
+ flex-basis: 8em;
+ background-color: var(--accent-color);
+ border: 2px solid var(--heavy-color);
+ width: 8em;
+ height: 2em;
+ padding: 2em;
+ border-radius: 1em;
+ text-align: center;
+ align-content: center;
+ text-decoration: none;
+ color: var(--dark-color);
+ font-weight: bold;
+ font-variant: small-caps;
+ }
+}
+
+#search {
+ margin: auto;
+ margin-bottom: 1em;
+ flex-grow: 1;
+ align-content: end;
+
+ input {
+ background-color: var(--light-color);
+ font-size: inherit;
+ color: var(--dark-color);
+ border: 2px solid var(--heavy-color);
+ border-radius: 1em 0 0 1em;
+ border-right: none;
+ padding: 0.5em;
+ width: 25em;
+ }
+
+ button {
+ background-color: var(--light-color);
+ font-size: inherit;
+ color: var(--dark-color);
+ border: 2px solid var(--heavy-color);
+ border-radius: 0 1em 1em 0;
+ border-left: none;
+ padding: 0.5em;
+ }
+}
+
+section {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 1em;
+ justify-content: center;
+ padding: 1em;
+ background-color: var(--heavy-color);
+
+ img {
+ border: 2px outset var(--dark-color);
+ width: 100%;
+ text-align: center;
+ box-sizing: border-box;
+ margin: auto;
+ }
+
+ >div {
+ overflow: auto;
+ flex-grow: 1;
+ flex-shrink: 0;
+ flex-basis: 8em;
+ padding: 1em;
+ height: 15em;
+ text-align: left;
+ text-decoration: none;
+ background-color: var(--light-color);
+ color: var(--dark-color);
+ border-radius: 1em;
+ font-weight: bold;
+
+ h2 {
+ margin-top: 0;
+ margin-bottom: 0.5rem;
+ padding: 0;
+ font-variant: small-caps;
+
+ a {
+ color: inherit;
+ text-decoration: none;
+ }
+ }
+ }
+}
+
+@media (max-width: 750px) {
+ html {
+ font-size: 0.8em;
+ }
+
+ header {
+ font-size: 1.5em;
+ }
+
+ nav>a {
+ padding: 1em;
+ height: 4em;
+ }
+
+ #search>input {
+ width: 15em;
+ }
+
+ section {
+ flex-direction: column;
+ flex-wrap: inherit;
+ }
+} \ No newline at end of file
diff --git a/static/style/login.css b/static/style/login.css
new file mode 100644
index 0000000..425393a
--- /dev/null
+++ b/static/style/login.css
@@ -0,0 +1,18 @@
+main>form {
+ display: grid;
+ grid-template-columns: auto 1fr;
+ gap: 0.5em;
+ margin: 0.5em;
+
+ label {
+ text-align: right;
+ }
+
+ input {
+ flex-grow: 1;
+ }
+
+ button {
+ grid-column: 1 / span 2;
+ }
+} \ No newline at end of file
diff --git a/static/style/style.css b/static/style/style.css
new file mode 100644
index 0000000..a2c894e
--- /dev/null
+++ b/static/style/style.css
@@ -0,0 +1,124 @@
+@font-face {
+ font-family: 'Montserrat';
+ font-style: normal;
+ font-weight: 400;
+ font-display: swap;
+ src: url(/static/montserrat/Montserrat-VariableFont_wght.ttf) format('woff2');
+}
+
+@font-face {
+ font-family: 'Montserrat';
+ font-style: italic;
+ font-weight: 400;
+ font-display: swap;
+ src: url(/static/montserrat/Montserrat-Italic-VariableFont_wght.ttf) format('woff2');
+}
+
+@font-face {
+ font-family: 'MsMadi';
+ font-style: normal;
+ font-weight: 400;
+ font-display: swap;
+ src: url(/static/msmadi/MsMadi-Regular.ttf) format('woff2');
+}
+
+html {
+ font-family: 'Montserrat', sans-serif;
+ --dark-color: hsl(65, 14%, 17%);
+ --heavy-color: hsl(65, 14%, 33%);
+ --accent-color: hsl(60, 50%, 60%);
+ --light-color: hsl(168, 6%, 83%);
+ background-color: var(--light-color);
+ margin: 0;
+ padding: 0;
+ height: 100%;
+}
+
+body {
+ margin: 0;
+ padding: 0;
+ min-height: 100%;
+ display: flex;
+ flex-direction: column;
+}
+
+#header-bg {
+ background-image: linear-gradient(transparent 80%, var(--light-color)), url("/static/img/bgcropped.webp");
+ background-size: cover;
+}
+
+header {
+ color: var(--dark-color);
+ text-align: center;
+ font-size: 2em;
+ transform: rotate(-2deg);
+ text-wrap: nowrap;
+ width: fit-content;
+ margin: auto;
+
+ h1 {
+ font-family: "MsMadi", cursive;
+ margin: 0;
+ }
+
+ span {
+ transform: translate(-2.5em, -1.25em);
+ font-size: 0.5em;
+ display: block;
+ }
+
+ a {
+ color: inherit;
+ text-decoration: none;
+ }
+}
+
+a {
+ color: var(--heavy-color);
+}
+
+footer {
+ display: flex;
+ flex-direction: row;
+ background-color: var(--dark-color);
+ color: var(--light-color);
+ padding: 0.35em;
+
+ >span {
+ flex-grow: 1;
+ text-align: center;
+ }
+}
+
+main {
+ flex-grow: 1;
+}
+
+main.centered {
+ width: 40%;
+ margin: auto;
+}
+
+#flashes {
+ font-size: 0.8em;
+ position: absolute;
+ top: 0;
+ right: 0;
+ margin: 1em;
+ z-index: 1;
+ border: 2px solid var(--dark-color);
+ background-color: var(--light-color);
+ color: var(--heavy-color);
+ font-weight: bold;
+ border-radius: 1em;
+
+ ul {
+ padding: 0;
+ margin: 0;
+ }
+
+ li {
+ padding: 0.25em;
+ list-style: none;
+ }
+} \ No newline at end of file
diff --git a/templates/base.html b/templates/base.html
new file mode 100644
index 0000000..8adc8df
--- /dev/null
+++ b/templates/base.html
@@ -0,0 +1,47 @@
+<!DOCTYPE html>
+<html lang="en">
+
+<head>
+ <title>Drosera Springs | {% block title %}Website{% endblock %}</title>
+ <link rel="stylesheet" href="{{ url_for('static', filename='style/style.css') }}">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <meta name="application-name" content="Drosera Springs" lang="en" />
+ <meta name="author" content="Morgana Hyde" />
+ <meta name="description"
+ content="Welcome to Drosera Springs! Find all the information you need about our vibrant resort city here. Located in Evergreen, Colorado, you're sure to have the time of your life!" />
+ {% block robots %}
+ <meta name="robots" content="noindex, nofollow, noarchive, nosnippet, noimageindex" />
+ {% endblock %}
+ {% block head %}{% endblock %}
+</head>
+
+<body>
+ {% block header %}
+ <div id="header-bg">
+ <header>
+ <a href="/">
+ <h1>Drosera Springs</h1><span>COLORADO, USA</span>
+ </a>
+ </header>
+ </div>
+ {% endblock %}
+ {% with messages = get_flashed_messages() %}
+ {% if messages %}
+ <dialog id="flashes" closedby="any" open>
+ <ul>
+ {% for message in messages %}
+ <li>{{ message }}</li>
+ {% endfor %}
+ </ul>
+ </dialog>
+ {% endif %}
+ {% endwith %}
+ {% block content %}{% endblock %}
+ <footer>
+ <span>City of Drosera Springs</span>
+ <span>4180 Absidy Street, Drosera Springs, CO 80439, United States</span>
+ <span>Website Managed by the Absidy Team</span>
+ </footer>
+</body>
+
+</html> \ No newline at end of file
diff --git a/templates/hyde.html b/templates/hyde.html
new file mode 100644
index 0000000..603c270
--- /dev/null
+++ b/templates/hyde.html
@@ -0,0 +1,102 @@
+<!DOCTYPE html>
+<html>
+
+<head>
+ <title>HYDEMATCH</title>
+ <link rel="stylesheet" href="{{ url_for('static', filename='style/hyde.css') }}">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+</head>
+
+<body>
+ <header>
+ <div>
+ <div>
+ <h1>HYDEMATCH</h1>
+ <strong>DROSERA SPRINGS WRESTLING DATABASE</strong>
+ </div>
+ <span></span>
+ <a href="/">Return to Main Site</a>
+ </div>
+ </header>
+ <main>
+ <h2>Morgana Hyde</h2>
+ <h3>General Data</h3>
+ <table class="datatable">
+ <tr>
+ <th>Current gimmick:</th>
+ <td>Morgana Hyde</td>
+ </tr>
+ <tr>
+ <th>Promotion:</th>
+ <td>Freelancer</td>
+ </tr>
+ </table>
+ <hr>
+ <h3>Personal Data</h3>
+ <table class="datatable">
+ <tr>
+ <th>Birthplace:</th>
+ <td>Drosera Springs, CO, USA</td>
+ </tr>
+ <tr>
+ <th>Gender:</th>
+ <td>Transfem</td>
+ </tr>
+ <tr>
+ <th>Height:</th>
+ <td>5'9"</td>
+ </tr>
+ <tr>
+ <th>WWW:</th>
+ <td><a href="/">https://icolotl.com/</a></td>
+ </tr>
+ </table>
+ <hr>
+ <h3>Career Data</h3>
+ <table class="datatable">
+ <tr>
+ <th>Alter egos:</th>
+ <td>Morgan Hyde</td>
+ </tr>
+ <tr>
+ <th>Roles:</th>
+ <td>Singles Wrestler</td>
+ </tr>
+ <tr>
+ <th>Beginning of in-ring career:</th>
+ <td>08.29.2026</td>
+ </tr>
+ </table>
+ <hr>
+ <h3>Matches</h3>
+ <table id="matchtable">
+ <tr>
+ <th id="matchno">#</th>
+ <th id="matchdate">Date</th>
+ <th id="matchdata">Match</th>
+ </tr>
+ {% for match in matches %}
+ <tr>
+ <td>{{ match.id }}</td>
+ <td>{{ match.date }}</td>
+ <td>
+ <div>{% if match.special %}<b>{{ match.special }}: </b>{% endif %}<strong>{{ match.victor
+ }}</strong>
+ defeats
+ {% with others = match.others.split(";") %}
+ <strong>{{ others[0] }}</strong>
+ {% for other in others[1:] %}
+ and <strong>{{ other }}</strong>
+ {% endfor %}
+ {% endwith %}
+ </div>
+ <small><strong>{{ match.event }}</strong> - Event @ {{ match.location }}</small>
+ </td>
+ </tr>
+ {% endfor %}
+ </table>
+ </main>
+ <footer>Disclaimer: This is a parody website and not associated with nor endorsed by CAGEMATCH.net</footer>
+</body>
+
+</html> \ No newline at end of file
diff --git a/templates/index.html b/templates/index.html
new file mode 100644
index 0000000..2618a68
--- /dev/null
+++ b/templates/index.html
@@ -0,0 +1,59 @@
+{% extends "base.html" %}
+
+{% block head %}
+<link rel="stylesheet" href="{{ url_for('static', filename='style/index.css') }}">
+{% endblock %}
+
+{% block title %} Homepage {%endblock%}
+
+{% block robots %}
+<meta name="robots" content="index, nofollow" />
+{% endblock %}
+{% block header %}{% endblock %}
+
+{% block content %}
+<main>
+ <header>
+ <a href="/">
+ <h1>Drosera Springs</h1><span>COLORADO, USA</span>
+ </a>
+ </header>
+ <form method="post" action="/search" id="search">
+ <input type="search" name="query" aria-label="Search"><button type="submit">Search</button>
+ </form>
+ <nav>
+ {% if session.username %}
+ <a href="/logout">Log Off</a>
+ {% else %}
+ <a href="/login">Resident Portal</a>
+ <a href="/guest">Guest Access</a>
+ {% endif %}
+ <a href="/eguide">Visitor's Guide</a>
+ <a href="/permits">Permits</a>
+ <a href="/news">eNewsletter</a>
+ <a href="/radio">Community Radio</a>
+ <a href="/absidy">Absidy Center</a>
+ <a href="/hyde">Local Wrestling</a>
+ <a href="https://git.icolotl.com">Open Data</a>
+ </nav>
+</main>
+<section>
+ <div>
+ <h2><a href="/absidy">Spotlight</a></h2>
+ <img src="/static/img/photography.webp" alt="Absidy Center Photography Showcase">
+ <a href="/absidy">For more photography and art, click here.</a>
+ </div>
+ <div>
+ <h2><a href="/news">News</a></h2>
+ <h3>{{ news.title }}</h3>
+ <small>Published {{ news.date }}</small>
+ <p>{{ news.content }}</p>
+ <a href="/news">For more, click here.</a>
+ </div>
+ <div>
+ <h2>Events</h2>
+ No events are planned.<br>
+ Check back later!
+ </div>
+</section>
+{% endblock %} \ No newline at end of file
diff --git a/templates/login.html b/templates/login.html
new file mode 100644
index 0000000..f0b450e
--- /dev/null
+++ b/templates/login.html
@@ -0,0 +1,19 @@
+{% extends "base.html" %}
+
+{% block head %}
+<link rel="stylesheet" href="{{ url_for('static', filename='style/login.css') }}">
+{% endblock %}
+
+{% block content %}
+<main class="centered">
+ <h2>D.S. Resident Login</h2>
+ <form method="post">
+ <label for="username">Username: </label>
+ <input type="text" name="username" autocomplete="username">
+ <label for="password">Password: </label>
+ <input type="password" name="password" autocomplete="current-password">
+ <button type="submit">Log In</button>
+ <input type="hidden" name="register" value="0">
+ </form>
+</main>
+{% endblock %} \ No newline at end of file