diff --git a/app/app.py b/app/app.py index d9b40b9..1aae832 100644 --- a/app/app.py +++ b/app/app.py @@ -1,63 +1,197 @@ from flask import Flask, request +import html import sqlite3 +from pathlib import Path app = Flask(__name__) +DB_PATH = Path(__file__).with_name("adventure.db") + def get_db(): - db = sqlite3.connect("adventure.db") + db = sqlite3.connect(DB_PATH) db.row_factory = sqlite3.Row return db + +BASE_CSS = """ +:root { + color-scheme: dark; +} +* { box-sizing: border-box; } +body { + margin: 0; + font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; + background: linear-gradient(135deg, #07121d 0%, #102a43 45%, #1e3a5f 100%); + color: #e2e8f0; + min-height: 100vh; +} +.shell { + min-height: 100vh; + display: grid; + place-items: center; + padding: 2rem 1rem; +} +.card { + width: min(760px, 100%); + background: rgba(7, 18, 29, 0.88); + border: 1px solid rgba(148, 163, 184, 0.25); + border-radius: 24px; + padding: 2rem; + box-shadow: 0 20px 60px rgba(0, 0, 0, 0.35); + backdrop-filter: blur(10px); +} +.card h1 { + margin-top: 0; + margin-bottom: 0.75rem; + font-size: 2rem; + color: #f8fafc; +} +.card p { + line-height: 1.7; + color: #cbd5e1; +} +.actions, .links { + display: flex; + flex-wrap: wrap; + gap: 0.75rem; + margin-top: 1.25rem; +} +.btn, .card a, .card button { + display: inline-block; + background: linear-gradient(135deg, #2563eb 0%, #06b6d4 100%); + color: #f8fafc; + border: none; + border-radius: 999px; + padding: 0.8rem 1.1rem; + text-decoration: none; + font-weight: 700; + cursor: pointer; + transition: transform 0.2s ease, box-shadow 0.2s ease; + box-shadow: 0 10px 25px rgba(6, 182, 212, 0.25); +} +.btn:hover, .card a:hover, .card button:hover { + transform: translateY(-2px); + box-shadow: 0 12px 30px rgba(37, 99, 235, 0.35); +} +.btn.secondary { + background: linear-gradient(135deg, #475569 0%, #64748b 100%); + box-shadow: 0 10px 25px rgba(100, 116, 139, 0.25); +} +form { + display: flex; + flex-wrap: wrap; + gap: 0.75rem; + align-items: center; + margin-top: 1rem; +} +input { + flex: 1 1 220px; + border: 1px solid rgba(148, 163, 184, 0.35); + border-radius: 999px; + padding: 0.8rem 1rem; + background: rgba(15, 23, 42, 0.9); + color: #f8fafc; +} +input:focus { + outline: 2px solid rgba(6, 182, 212, 0.45); + border-color: transparent; +} +""" + +BASE_JS = """ +window.addEventListener('DOMContentLoaded', () => { + const firstInput = document.querySelector('input'); + if (firstInput) firstInput.focus(); +}); +""" + + +def render_page(title, body_html): + return f""" + + + + + {html.escape(title)} + + + +
+
+ {body_html} +
+
+ + +""" + + @app.route("/") +@app.route("/app") +@app.route("/app/") def start(): - return """""" + '

Verlassenes Raumschiff

' \ - '

Du bist der einzige Überlebende an Bord. Erkunde das Schiff und aktiviere das Notsignal.

' \ - 'Mission starten
' + body = """ +

Verlassenes Raumschiff

+

Du bist der einzige Überlebende an Bord. Erkunde das Schiff und aktiviere das Notsignal.

+
+ Mission starten +
+ """ + return render_page("Verlassenes Raumschiff", body) + @app.route("/raum/", methods=["GET", "POST"]) +@app.route("/app/raum/", methods=["GET", "POST"]) def raum(id): db = get_db() r = db.execute("SELECT * FROM raeume WHERE id=?", (id,)).fetchone() if not r: db.close() - return '

Raum nicht gefunden

' + return render_page( + "Raum nicht gefunden", + '

Raum nicht gefunden

Der angeforderte Raum existiert nicht.

' + ) if r["raetsel_frage"]: if request.method == "POST": if request.form.get("antwort", "").strip() == r["raetsel_antwort"]: db.close() - return '

Notsignal erfolgreich aktiviert. Rettung ist unterwegs.

' + return render_page( + "Notsignal aktiviert", + '

Notsignal erfolgreich aktiviert

Rettung ist unterwegs.

' + ) db.close() - return '

Falscher Code

Der KI-Kern reagiert nicht.

' \ - 'nochmal versuchen' + return render_page( + "Falscher Code", + '

Falscher Code

Der KI-Kern reagiert nicht.

' + ) db.close() - return '

' + r["name"] + '

' \ - '

' + r["beschreibung"] + '

' \ - '
' + r["raetsel_frage"] + \ - '
' + body = f""" +

{html.escape(r['name'])}

+

{html.escape(r['beschreibung'])}

+
+ + +
+ """ + return render_page(html.escape(r["name"]), body) ausgaenge = db.execute( "SELECT richtung, nach_raum FROM ausgaenge WHERE von_raum=?", (id,) ).fetchall() db.close() - html = '

' + r["name"] + '

' - html += '

' + r["beschreibung"] + '

' + body = f""" +

{html.escape(r['name'])}

+

{html.escape(r['beschreibung'])}

+ " + return render_page(html.escape(r["name"]), body) + if __name__ == "__main__": app.run(host="0.0.0.0", port=9004)