diff --git a/security.py b/security.py
index f3012eb..5ab9d46 100644
--- a/security.py
+++ b/security.py
@@ -4,6 +4,8 @@ from __future__ import annotations
import os
+from urllib.parse import urlparse
+
from flask import Flask, request
from flask_limiter import Limiter
from flask_limiter.util import get_remote_address
@@ -34,6 +36,7 @@ def configure_app(flask_app: Flask) -> None:
x_for=1,
x_proto=1,
x_host=1,
+ x_port=1,
)
limiter.init_app(flask_app)
@@ -56,7 +59,14 @@ def configure_app(flask_app: Flask) -> None:
def external_base_url() -> str:
"""Build public base URL (respects reverse proxy and PREFERRED_URL_SCHEME)."""
- preferred = os.environ.get("PREFERRED_URL_SCHEME", "").strip()
- if preferred:
- return f"{preferred}://{request.host}"
- return request.host_url.rstrip("/")
+ host_url = request.host_url.rstrip("/")
+ preferred = os.environ.get("PREFERRED_URL_SCHEME", "").strip().lower()
+ if not preferred:
+ return host_url
+
+ # Use netloc from host_url (honours ProxyFix / X-Forwarded-Host), not request.host
+ # alone, which can still include the internal upstream port behind a reverse proxy.
+ netloc = urlparse(host_url).netloc
+ if not netloc:
+ netloc = request.host
+ return f"{preferred}://{netloc}"
diff --git a/static/style.css b/static/style.css
index 2d7ac90..cc840e5 100644
--- a/static/style.css
+++ b/static/style.css
@@ -601,6 +601,7 @@ tr:hover td { background: var(--bg-hover); }
.landing-page {
min-height: 100vh;
display: flex;
+ flex-direction: column;
align-items: center;
justify-content: center;
padding: 24px;
@@ -661,6 +662,35 @@ tr:hover td { background: var(--bg-hover); }
.landing-lang { margin-top: 8px; }
+.site-footer {
+ text-align: center;
+ padding: 16px 24px 20px;
+ font-size: 0.78rem;
+ color: var(--text-muted);
+ border-top: 1px solid var(--border);
+}
+
+.site-footer p {
+ margin: 0;
+}
+
+.site-footer a {
+ color: var(--accent);
+ text-decoration: none;
+}
+
+.site-footer a:hover {
+ text-decoration: underline;
+}
+
+.landing-page .site-footer {
+ width: 100%;
+ max-width: 520px;
+ background: transparent;
+ border-top: none;
+ padding-top: 0;
+}
+
/* Viewer link banner */
.viewer-banner {
display: flex;
diff --git a/templates/_footer.html b/templates/_footer.html
new file mode 100644
index 0000000..b9345d1
--- /dev/null
+++ b/templates/_footer.html
@@ -0,0 +1,3 @@
+
diff --git a/templates/index.html b/templates/index.html
index 41847be..7d3dc5d 100644
--- a/templates/index.html
+++ b/templates/index.html
@@ -73,5 +73,6 @@
+ {% include '_footer.html' %}