diff --git a/muxplex/frontend/login.html b/muxplex/frontend/login.html
new file mode 100644
index 0000000..e29544b
--- /dev/null
+++ b/muxplex/frontend/login.html
@@ -0,0 +1,192 @@
+
+
+
+
+
+ Sign in — muxplex
+
+
+
+
+
+

+
+
+
+ Incorrect credentials. Please try again.
+
+
+
+
+
+
+
+
diff --git a/muxplex/tests/test_frontend_html.py b/muxplex/tests/test_frontend_html.py
index bc458cc..1a1fe4d 100644
--- a/muxplex/tests/test_frontend_html.py
+++ b/muxplex/tests/test_frontend_html.py
@@ -5,6 +5,7 @@ import pathlib
from bs4 import BeautifulSoup, Tag
HTML_PATH = pathlib.Path(__file__).parent.parent / "frontend" / "index.html"
+LOGIN_PATH = pathlib.Path(__file__).parent.parent / "frontend" / "login.html"
# Parse once per module — tests are read-only so sharing is safe.
_SOUP: BeautifulSoup = BeautifulSoup(HTML_PATH.read_text(), "html.parser")
@@ -263,3 +264,64 @@ def test_html_element_classes() -> None:
assert expected_class in classes, (
f"#{el_id} is missing class '{expected_class}' — {reason}. Has: {classes}"
)
+
+
+# ── Login page tests ─────────────────────────────────────────────────────────
+
+
+def _get_login_soup() -> BeautifulSoup:
+ """Load and parse login.html — raises FileNotFoundError if file is missing."""
+ return BeautifulSoup(LOGIN_PATH.read_text(), "html.parser")
+
+
+def test_login_html_exists() -> None:
+ """login.html must exist in the frontend directory."""
+ assert LOGIN_PATH.exists(), f"Missing login.html at {LOGIN_PATH}"
+
+
+def test_login_html_has_form() -> None:
+ """login.html must have a